.net - type - unity container example
Unity 2.0: ¿Cómo usar Resolver con ResolverOverride? (3)
Empecé a hacer más y más trabajo con Unity . Observé que el método Resolver toma un argumento de parámetros ResolverOverride .
¿Puede alguien darme un ejemplo de cómo puedo usar ResolverOverride o señalarme alguna otra fuente donde pueda obtener más pistas?
Como habrás notado, esta es una característica nueva (y realmente genial) de Unity 2. Esta característica te permite
- pasar parámetros al constructor en el momento en que resuelve la clase. En la unidad 1, puede establecer un solo valor en el momento en que se registra el tipo mediante el nuevo InjectionConstructor (...)
Hay ParameterOverride : ResolverOverride
Una clase ResolverOverride que le permite anular un parámetro con nombre pasado a un constructor.
- Lo mismo para las dependencias con
DependencyOverride : ResolverOverride
Una clase que anula el valor inyectado siempre que exista una dependencia del tipo dado, independientemente de dónde aparezca en el gráfico del objeto.
- Lo mismo para las propiedades con
PropertyOverride : ResolverOverride
Un ResolverOverride que le permite anular 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 override which appears only in unity 2.0) classes will have 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 tengo idea de por qué Google guarda silencio sobre eso.
Las citas son del código fuente de Unity xml docs.
En caso de que alguien esté interesado, he creado un método de extensión que hace que la sintaxis para resolver usando ParameterOverride
un poco más fácil de leer. El método es como sigue:
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 :)
}
}
Con esto, puede volver a escribir el ejemplo ParameterOverride de la siguiente manera:
var service = container.Resolve<IConcreteService>(new {val=3});
Espero que esto sea útil para alguien ...
Solo para agregar mi 2c. Simplemente puede agregar un ParameterOverrides como así:
Container.Resolve<IConcreteService>(new ParameterOverrides
{
{"val", 42}
});