2011-09-20 7 views
7

¿Es posible insertar una lista de dependencias de esta manera en Unity u otro tipo de bibliotecas IoC?Unity .NET: Lista de dependencias

public class Crawler 
{ 
    public Crawler(IEnumerable<IParser> parsers) 
    { 
     // init here... 
    } 
} 

De esta manera puedo registrar varias IParser en mi recipiente y luego resolverlos.

¿Es posible? Gracias

+2

posible duplicado de [Resolviendo IEnumerable con Unity] (http://stackoverflow.com/questions/1961549/resolving-ienumerablet-with-unity) –

Respuesta

0

No es que diga que está mal, pero parece que estás tratando de resolver un modelo de complemento que puedes administrar fácilmente con el uso de MEF. Las sugerencias se heredarán Exportar de la interfaz y luego ImportMany cuando necesite los analizadores.

-1

sí, usted puede .. puede ver los inyectores de dependencia. Soy un gran admirador del proyecto Autofac.

Otra opción es Ninject,

9

Es posible, pero es necesario aplicar algunas soluciones. Primero debe registrar cada IParser con un nombre en el contenedor Unity. En segundo lugar, debe registrar una asignación de IParser [] a IEnumerable <IParser> en el contenedor. De lo contrario, el contenedor no puede inyectar los analizadores al constructor. Así es como lo he hecho antes.

IUnityContainer container = new UnityContainer(); 

container.RegisterType<IParser, SuperParser>("SuperParser"); 
container.RegisterType<IParser, DefaultParser>("DefaultParser"); 
container.RegisterType<IParser, BasicParser>("BasicParser"); 
container.RegisterType<IEnumerable<IParser>, IParser[]>(); 
container.RegisterType<Crawler>(); 

Crawler crawler = container.Resolve<Crawler>(); 

He descartado esta solución mediante la introducción de una fábrica, que encapsula la unidad para construir los tipos necesarios. Así es como lo haría en tu caso.

public interface IParserFactory{ 
    IEnumerable<IParser> BuildParsers(); 
} 

public class UnityParserFactory : IParserFactory { 
    private IUnityContainer _container; 

    public UnityParserFactory(IUnityContainer container){ 
    _container = container; 
    } 

    public IEnumerable<IParser> BuildParsers() { 
    return _container.ResolveAll<IParser>(); 
    } 
} 

public class Crawler { 
    public Crawler(IParserFactory parserFactory) { 
    // init here... 
    } 
} 

Con esto se puede registrar los tipos de la siguiente manera:

IUnityContainer container = new UnityContainer(); 

container.RegisterType<IParser, SuperParser>(); 
container.RegisterType<IParser, DefaultParser>(); 
container.RegisterType<IParser, BasicParser>(); 
container.RegisterType<IParserFactory, UnityParserFactory>(); 

Crawler crawler = container.Resolve<Crawler>(); 
0

Como cuestión de hecho, no sé cualquier recipiente que hace no lo soportan.

Sin embargo, como consejo general, debe evitar la inserción de listas de servicios en los consumidores si es posible, envolviendo esa lista en un composite e inyecte ese compuesto en los consumidores. Si no envuelve la lista en un compuesto, la aplicación se complicará con los bucles adicionales foreach o lo que sea necesario para procesar esa lista de dependencias. Si bien esto no parece malo, los consumidores de estas dependencias no deberían preocuparse. Pero lo que es peor, cuando queremos cambiar la forma en que se maneja la lista de servicios, tendremos que pasar por la aplicación completa, lo cual es una violación del principio DRY.

Este consejo no se cumple cuando el consumidor (en su caso, el Crawler) es parte del Composition Root en lugar de la aplicación en sí. Además, cuando la aplicación solo tiene un solo consumidor que toma esta dependencia, puede que no sea tan importante.

0

Hay formas de lograr esto en Unity.Por ejemplo,

http://sharpsnmplib.codeplex.com/SourceControl/changeset/view/5497af31d15e#snmpd%2fapp.config

<register type="UserRegistry"> 
     <lifetime type="singleton" /> 
     <constructor> 
     <param name="users" dependencyType="User[]" /> 
     </constructor> 
    </register> 

Este constructor requiere una matriz de objetos de usuario, y todos estos objetos definidos en este contenedor se inyectan por Unity en él cuando se crea el objeto userRegistry.