Пользовательский контейнер IOC - нужна помощь по 2/3 типам

Предпосылки

Чтобы помочь мне лучше понять IOC и то, как его использовать, я хочу создать пример всех трех техник IOC: внедрение конструктора, внедрение установщика и внедрение интерфейса без необходимости использовать стороннюю платформу. Я думаю, что у меня есть базовый пример внедрения конструктора, но я борюсь с установщиком и внедрением интерфейса.

Мой вопрос

Как бы вы подошли к написанию интерфейса и внедрению сеттера с нуля?

Вот мои мысли, дайте мне знать, на правильном ли я пути.

Внедрение интерфейса:

  1. Прокрутите разрешенные объекты, экземпляры которых созданы с помощью внедрения конструктора, проверьте, какие интерфейсы реализованы в interfaceDependencyMap.
  2. Определите какой-то тип interfaceDependencyMap, чтобы связать интерфейс с реализацией.
  3. Разрешить реализацию с помощью interfaceDependencyMap
  4. Назначить соответствующее свойство объекту, инициализированному с помощью внедрения конструктора

Внедрение установщика:

  1. Цикл через разрешенные объекты, экземпляры которых созданы с помощью внедрения конструктора
  2. Определить какой-то тип setterInjectionMap
  3. Определите ожидаемый параметр из MethodInfo, используя сопоставления конструктора
  4. Вызовите метод установки, передающий в разрешенный объект параметра

Вот что у меня есть для внедрения конструктора

public class Program
{
    static void Main(string[] args)
    {
        //
        //instead of doing this:
        //
        //ICreditCard creditCard = new Visa();
        //var customer = new Customer(creditCard);
        //customer.Charge();


        var resolver = new Resolver();

        //map the types in the container
        resolver.Register<Customer, Customer>();
        resolver.Register<ICreditCard, Visa>();

        //because the customer constructor has an ICreditCard parameter
        //our container will automatically instantiate it recursively
        var customer = resolver.Resolve<Customer>();

        customer.Charge();

    }
}

public interface ICreditCard
{
    string Charge();
}

public class Visa : ICreditCard
{
    public string Charge()
    {
        return "Charging Visa";
    }
}

public class MasterCard : ICreditCard
{
    public string Charge()
    {
        return "Charging MasterCard";
    }
}

public class Customer
{
    private readonly ICreditCard _creditCard;

    public Customer(ICreditCard creditCard)
    {
        this._creditCard = creditCard;
    }

    public void Charge()
    {
        _creditCard.Charge();
    }
}


public class Resolver
{
    private Dictionary<Type, Type> dependencyMap = new Dictionary<Type, Type>();

    public T Resolve<T>()
    {
        return (T) Resolve(typeof (T));
    }

    private object Resolve(Type typeToResolve)
    {
        Type resolvedType = null;

        try
        {
            resolvedType = dependencyMap[typeToResolve];
        }
        catch
        {
            throw new Exception(string.Format("could not resolve type {0}", typeToResolve.FullName));
        }

        var firstConstructor = resolvedType.GetConstructors().First();
        var constructorParameters = firstConstructor.GetParameters();
        if (constructorParameters.Count() == 0)
            return Activator.CreateInstance(resolvedType);

        IList<object> parameters = constructorParameters.Select(parameterToResolve => Resolve(parameterToResolve.ParameterType)).ToList();

        return firstConstructor.Invoke(parameters.ToArray());
    }

    public void Register<TFrom, TTo>()
    {
        dependencyMap.Add(typeof (TFrom), typeof (TTo));
    }
}
5
задан Eric Walter 8 December 2011 в 17:32
поделиться