2010-05-11 9 views

Respuesta

92

Como usted ha notado esta es una nueva (y realmente fresca función) de la Unidad 2. Esta característica le deja

  • pasar parámetros de constructor en el momento en que se resuelva el clase. En la unidad 1 se puede establecer sólo un valor en el momento en que se registre a través de tipo nuevo InjectionConstructor (...)

Hay ParameterOverride : ResolverOverride

clase

Un ResolverOverride que le permite anular un parámetro denominado pasado a un constructor .

  • mismo para dependencias con DependencyOverride : ResolverOverride

Una clase que anula el valor inyectaron cada vez que hay una dependencia del tipo dado, independientemente de donde aparece en el objeto grafico.

  • mismo para propiedades con PropertyOverride : ResolverOverride

Un ResolverOverride que permite sustituir el valor de una propiedad especificada.

Ejemplo

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; } 

    } 
} 

no tienen idea de qué hace Google guarda silencio acerca de eso.

Las cotizaciones provienen del código fuente de Unity xml docs.

+1

Gracias por una respuesta increíble. +1 – Vadim

+0

Esto fue de gran ayuda. Muy bien explicado. –

+1

+1 ¡Explicación perfecta! –

43

Por si a alguien le interesa, he hecho un método de extensión que hace que la sintaxis para resolver usando ParameterOverride sea un poco más fácil de leer. El método es el siguiente:

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 :) 
    } 
} 

Con esto, se puede reescribir el ejemplo ParameterOverride de la siguiente manera:

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

Espero que esto sea útil para alguien ...

+0

¡Manera elegante para anulación de parámetros, gracias! –

+0

Acepto - +1 voto para esto. – TravisWhidden

+0

Buen trabajo. +1 voto para este – Spock

13

Sólo para añadir mi 2c.Usted puede simplemente agregar un ParameterOverrides como así:

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