views:

549

answers:

2

The Unity documentation states:

if a class that developers instantiate using the Resolve method of the Unity container has a constructor that defines one or more dependencies on other classes, the Unity container automatically creates the dependent object instance specified in parameters of the constructor

This is great, but most often I don't specify classes for injection but interfaces, so as to keep things decoupled.

So how can I take advantage of Unity's automatic injection when I .Resolve<> a class which specifies interface injection instead of class injection?

i.e. in the following code, how can I make it work when I change my Customer constructor to "public Customer(ILogger logger)"?

using System;
using Microsoft.Practices.Unity;

namespace TestUnityInjection23
{
    public class Program
    {
        static void Main(string[] args)
        {
            Customer customer1 = new Customer(new BasicLogger());
            //Customer customer2 = new Customer(new AdvancedLogger()); //can't use this since Customer only accepts BasicLogger

            UnityContainer container = new UnityContainer();
            container.RegisterType<Customer>();
            container.RegisterType<ILogger, BasicLogger>();
            Customer customer3 = container.Resolve<Customer>();

            Console.ReadLine();
        }
    }

    public class Customer
    {
        public Customer(BasicLogger logger) //would like to have Customer depend on ILogger here so logger can be swapped out
        {
            logger.WriteToLog("creating the customer");
        }
    }

    public interface ILogger
    {
        void WriteToLog(string text);
    }

    public class BasicLogger : ILogger
    {

        public void WriteToLog(string text)
        {
            Console.WriteLine(text);
        }
    }

    public class AdvancedLogger : ILogger
    {
        public void WriteToLog(string text)
        {
            Console.WriteLine("*** {0} ***", text);
        }
    }

}
+1  A: 

I've never used Unity, but every other DI framework I know does that and I'm sure Unity must do that too.

Have you tried changing the Customer constructor and seeing if it works? Cos it should.

gcores
yes it does work if I do that, problem was I had been trying "container.RegisterType<ILogger>()" which of course doesn't specify if BasicLogger or AdvancedLogger should be injected at runtime. I was wondering how the container was going to decide which to use, makes sense now, thanks
Edward Tanguay
A: 

Not sure if too late but I think

using (IUnityContainer container = new UnityContainer()) { container.RegisterType();

            container
                .RegisterType<ILogger, BasicLogger>()
                .Configure<InjectedMembers>()
                .ConfigureInjectionFor<Customer>(new InjectionConstructor(typeof(BasicLogger)));

            var customer3 = container.Resolve<Customer>();
        }
        Console.ReadLine();

public class Customer { public BasicLogger Logger { get; set; } public Customer(ILogger logger) { logger.WriteToLog("creating the customer"); } }

will do the trick