Как заставить автоматическую инъекцию Unity работать на конструкторах с внедрением интерфейса? - PullRequest
2 голосов
/ 18 марта 2009

Документация Unity гласит:

если класс, созданный разработчиками используя метод Resolve в Unity Контейнер имеет конструктор, который определяет одну или несколько зависимостей от другие классы, контейнер Unity автоматически создает зависимую экземпляр объекта , указанный в параметры конструктора

Это здорово, но чаще всего я не указываю классы для инъекций, но интерфейсы , чтобы сохранить вещи развязаны.

Итак, как я могу воспользоваться преимуществами автоматической инъекции Unity, когда я .Resolve <> класс, который определяет внедрение интерфейса вместо внедрения класса?

т.е. в следующем коде, как я могу заставить его работать, когда я изменяю свой конструктор Customer на « 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);
        }
    }

}

Ответы [ 3 ]

1 голос
/ 23 августа 2009

Не уверен, что слишком поздно, но я думаю

использование (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");
            }
        }

сделает свое дело

1 голос
/ 18 марта 2009

Я никогда не использовал Unity, но любая другая DI-инфраструктура, которую я знаю, делает это, и я уверен, что Unity должна это делать.

Вы пытались изменить конструктор Customer и посмотреть, работает ли он? Потому что это должно.

0 голосов
/ 19 октября 2011

Используйте универсальный

public interface ILogger<T> where T: class
{

}

public class BasicLogger:ILogger<BasicLogger>
{

}

public class AdvanceLogger:ILogger<AdvanceLogger>
{

}
...