2010-05-11 2 views
57

Я начал делать все больше и больше работы с Unity. Я замечаю, что метод Resolver принимает параметры аргумент ResolverOverride.Unity 2.0: Как использовать Resolve with ResolverOverride?

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

ответ

92

Как вы уже заметили, что это новый (и действительно полезная функция) Единения 2. Эта функция позволяют Вам

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

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

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

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

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

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

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 хранит молчание по этому поводу.

Цитаты из исходных кодов Unity xml docs.

+1

Спасибо за отличный ответ. +1 – Vadim

+0

Это была отличная помощь. Очень хорошо объяснено. –

+1

+1 Отличное объяснение! –

43

На всякий случай кто-то заинтересован, я сделал метод расширения, который упрощает чтение синтаксиса для разрешения с помощью 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}); 

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

+0

Элегантный способ переопределения параметра, спасибо! –

+0

Согласен - +1 голосовать за это. – TravisWhidden

+0

Хорошая работа. +1 голос за это – Spock

13

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

Container.Resolve<IConcreteService>(new ParameterOverrides 
{                     
    {"val", 42} 
}); 
Смежные вопросы