14

I have the following classes:

public interface IServiceA
{
    string MethodA1();
}

public interface IServiceB
{
    string MethodB1();
}

public class ServiceA : IServiceA
{
    public IServiceB serviceB;

    public string MethodA1()
    {
        return "MethodA1() " +serviceB.MethodB1();
    }
}

public class ServiceB : IServiceB
{
    public string MethodB1()
    {
        return "MethodB1() ";
    }
}

I use Unity for IoC, my registration looks like this:

container.RegisterType<IServiceA, ServiceA>(); 
container.RegisterType<IServiceB, ServiceB>(); 

When I resolve a ServiceA instance, serviceB will be null. How can I resolve this?

Dariusz Woźniak
  • 9,640
  • 6
  • 60
  • 73
Jin Ho
  • 3,565
  • 5
  • 23
  • 25

1 Answers1

20

You have at least two options here:

You can/should use constructor injection, for that you need a constructor:

public class ServiceA : IServiceA
{
    private IServiceB serviceB;

    public ServiceA(IServiceB serviceB)
    {
        this.serviceB = serviceB;
    }

    public string MethodA1()
    {
        return "MethodA1() " +serviceB.MethodB1();
    }
}

Or Unity supports property injection, for that you need a property and the DependencyAttribute:

public class ServiceA : IServiceA
{
    [Dependency]
    public IServiceB ServiceB { get; set; };

    public string MethodA1()
    {
        return "MethodA1() " +serviceB.MethodB1();
    }
}

The MSDN site What Does Unity Do? is a good starting point for Unity.

nemesv
  • 138,284
  • 16
  • 416
  • 359
  • 8
    If you have a choice between constructor and property injection, I think you should choose constructor injection. Property injection will make the class dependent on unity or some other caller 'remembering' that they need to supply that dependency. Constructor injection makes it clear to anybody trying to use the class that the dependency is essential for the class. – Carlos Apr 23 '12 at 16:40
  • And if the class has multiple dependencies, that are not all needed in certain calls? Will they all be instantiated? Or will they only be instantiated when accessed, like above: serviceB.method() ? @Carlos – Legends Apr 12 '15 at 14:10
  • 1
    @Legends all your dependencies will be instated and inject when the ServiceA is created even if you don't use them in all your method. Unity does not support lazy instantiation out of the box but it can be added as extension: http://pwlodek.blogspot.hu/2010/05/lazy-and-ienumerable-support-comes-to.html – nemesv Apr 12 '15 at 16:26
  • I tried the following: `container.RegisterType();` `container.RegisterType(new InjectionProperty("CDA", container.Resolve()));` I have marked the property CDA residing in SampleBF as Dependency. My question, will it work if I instantiate the SampleBF manually? Because that's the way I do it and I always get "Object reference not set to an instance" when trying to aaccess the property CDA. – Legends Apr 13 '15 at 10:06
  • Ok, I have to resolve the calling class also by unity (in my case ISampleBF), then it works. – Legends Apr 13 '15 at 10:12
  • @nemesv, Unity 3 now supports lazy instantiation, but I guess it only makes sense if there is heavy work done during construction. Here is the link to Unity 3 Deferred resolution: https://msdn.microsoft.com/en-us/library/dn178463%28v=pandp.30%29.aspx#sec33 – Legends Apr 16 '15 at 21:47