1

I have a class that needs a dependency injecting. As the class is already an implementation of another abstraction, and its 'sibling' implementations may not share the same dependencies, I am attempting to use property injection and not constructor injection.

(All these classes/interface names are just for illustrative purposes)

My IProvider abstraction:

public interface IProvider
{
    void ProviderMethod();
}

My IProvider implementation (with the IData dependency I want to inject):

public class ProviderClass : IProvider
{
    // How do I inject this dependency?
    [Dependency]
    public IData data { get; set; }

    public void ProviderMethod()
    {
        // Can't do this as data == null!
        data.DataMethod();
    }
}

Another IProvider implementation (example to show that it doesn't have the same dependencies):

public class AnotherProviderClass : IProvider
{
    // No data dependency here!!

    public void ProviderMethod()
    {
        // Do other stuff here
    }
}

Example IData abstraction and implementation:

public interface IData
{
    void DataMethod();
}

public class DataClass : IData
{
    public void DataMethod();
}

What I need to know is: How do I successfully inject the property dependency (IData) into ProviderClass using Unity (my IOC container of choice)?

I have tried all manner of Unity registering options (RegisterType, RegisterInstance, Resolve...) but my injected property always ends up as NULL. I want to do this right and not just force random code in until it just manages to work.

Or is there a better way of injecting (optional) dependencies into 'sibling' classes?

Incidentally, my initial IProvider implementations are created via an abstract factory, so maybe that might be another area I should focus this IData dependency on(?)

  • 1
    It's unclear to me why you don't do constructor injection. Can you elaborate on that? – Steven Apr 04 '14 at 10:54
  • Mainly because the dependency is optional, and other IProvider implementations may have many of their own dependencies that are unique to their class. The IProvider implementations are returned from an abstract factory (say IProviderFactory); as each new IProvider implementation is added the factory would have to accommodate their growing number of these in its own injection policy (potential constructor parameter bloat?). – Jeremy Page Apr 04 '14 at 12:16
  • The right way to do property dependency injection using Unity: You let the resolved types contain the correct configuration and don't repeat yourself. If you need cross cutting concerns to inject logging into multiple objects, for example, you use Interceptor. –  Mar 20 '17 at 12:59

1 Answers1

4

You should still use constructor injection because dependencies should hardly ever be optional.

You are trying to prevent constructor over-injection in the IProviderFactory implementation, and you probably don't want to inject the container into your factory to prevent falling into the Service Locator anti-pattern.

If however you define your IProviderFactory implementation INSIDE your Composition Root, you prevent yourself from doing Service Locator, even though you inject the container, since Service Locator is not about mechanics.

So you should define your ProviderFactory implementation as close to your Unity configuration as possible and it should look something like this:

public class ProviderFactory : IProviderFactory
{
    private readonly Dictionary<string, Type> providerTypes;
    private readonly Container container;

    public ProviderFactory(Dictionary<string, Type> providerTypes, 
        Container container) {
        this.providerTypes = providerTypes;
        this.container = container;
    }

    public IProvider CreateProvider(string name) {
        return (IProvider)this.container.Resolve(this.providerTypes[name]);
    }
}

This implementation can be registered as singleton in Unity. This saves you from having to do constructor over-injection into your factory, while staying away from Service Locator.

Steven
  • 166,672
  • 24
  • 332
  • 435