Unity 2.0: Как использовать Resolve с ResolverOverride?

Я начал все больше и больше работать с Unity. Я замечаю, что метод Resolver принимает аргумент params ResolverOverride.

Может ли кто-нибудь дать мне пример того, как я могу использовать ResolverOverride или указать мне другой источник, где я могу получить дополнительные подсказки.

Ответ 1

Как вы заметили, это новая (и очень крутая функция) Unity 2. Эта функция позволяет вам

  • передать параметры конструктору в момент, когда вы разрешаете класс. В единстве 1 вы можете установить только одно значение в момент, когда вы регистрируете тип через новый InjectionConstructor (...)

Существует ParameterOverride : ResolverOverride

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

  • то же самое для зависимостей с DependencyOverride : ResolverOverride

Класс, который переопределяет значение вводится всякий раз, когда имеется зависимость данного типа, независимо от того, где он графа объектов.

  • для свойств с PropertyOverride : ResolverOverride

A ResolverOverride, позволяющий переопределить значение для указанного свойства.

Пример

using System;
using Microsoft.Practices.Unity;

namespace ConsoleApplication1 {
    class Program {
        static void Main(string[] args) {

            var container = new UnityContainer();

            //ParameterOverride example

            container.RegisterType<IConcreteService, ConcreteService>(
                new InjectionConstructor(7) //Old way to pass value to constructor - not flexible. 
                                            //All resolved (without ovverride wich aapears only in unity 2.0) classes will hav val=7
                );

            var service0 = container.Resolve<IConcreteService>();
            Console.WriteLine(service0.Val); //prints 7

            var service = container.Resolve<IConcreteService>(new ParameterOverride("val", 3));
            Console.WriteLine(service.Val); // prints 3

            var service2 = container.Resolve<IConcreteService>(new ParameterOverride("val", 5));
            Console.WriteLine(service2.Val); // prints 5

            Console.ReadLine();

            //DependencyOverride example

            var b0 = container.Resolve<B>(new DependencyOverride<IConcreteService>(new ConcreteService(42)));
            Console.WriteLine(b0.Service.Val); //print 42
            Console.WriteLine(b0.Service1.Val); //print 42

            var b = container.Resolve<B>(new DependencyOverride<IConcreteService>(new ConcreteService(-42)));
            Console.WriteLine(b.Service.Val); // print -42
            Console.WriteLine(b.Service1.Val); // print -42

            Console.ReadLine();

            //PropertyOverride example 

            var b1 = container.Resolve<B>(new PropertyOverride("Service", new ConcreteService(42)), 
                new PropertyOverride("Service1", new ConcreteService(-42)));
            Console.WriteLine(b1.Service.Val); //print 42
            Console.WriteLine(b1.Service1.Val); //print -42

            Console.ReadLine();



        }
    }

    public interface IConcreteService {
        int Val { get; set; }
    }
    public class ConcreteService : IConcreteService {

        public int Val { get; set; }

        public ConcreteService(int val) {
            Val = val;
        }
    }

    public class B {
        [Dependency]
        public IConcreteService Service{ get; set; }

        [Dependency]
        public IConcreteService Service1 { get; set; }

    }
}

Не знаю, почему Google молчит об этом.

Цитаты из XML-документов исходного кода Unity.

Ответ 2

На всякий случай кто-то заинтересован, я сделал метод расширения, который упрощает чтение синтаксиса для разрешения с помощью ParameterOverride. Метод выглядит следующим образом:

public static class UnityExtensions
{
    public static T Resolve<T>(this IUnityContainer container, object parameterOverrides)
    {
        var properties = parameterOverrides
            .GetType()
            .GetProperties(BindingFlags.Public | BindingFlags.Instance);
        var overridesArray = properties
            .Select(p => new ParameterOverride(p.Name, p.GetValue(parameterOverrides, null)))
            .Cast<ResolverOverride>()
            .ToArray();
        return container.Resolve<T>(null, overridesArray); //null needed to avoid a StackOverflow :)
    }
}

С этим вы можете переписать пример ParameterOverride следующим образом:

var service = container.Resolve<IConcreteService>(new {val=3});

Я надеюсь, что это полезно для кого-то...

Ответ 3

Просто добавьте свой 2c. Вы можете просто добавить ParameterOverrides следующим образом:

Container.Resolve<IConcreteService>(new ParameterOverrides
{                                                                                   
  {"val", 42}
});