2011-11-18 23 views
10

Mi objetivo es que el constructor inyecto una matriz de objetos que implementen una interfaz.Inyección de matrices con Unity

La siguiente es la forma en que actualmente lo tengo.

  Container 

        .RegisterInstance<Company>(ParseCompany(args[1]) 

        .RegisterInstance<eTargets>(ParseTargets(args[2])) 

        .RegisterInstance<ILoader[]>(new ILoader[] { 
         Container.Resolve<CustomerLoader>(), 
         Container.Resolve<PaymentLoader(), 
         Container.Resolve<InvoiceLoader() 
        }); 

es típico para llamar resolver de configuración del contenedor de esta manera o hay una manera más estándar para lograr la misma cosa?

Respuesta

25

Unity entiende nativamente las matrices, por lo que no hay ninguna razón para hacerlo tan complicado. Simplemente registre el ILoaders que desea incluir y resolver los gráficos de objetos normalmente. Auto-cableado se hará cargo del resto:

container.RegisterType<ILoader, FooLoader>("foo"); 
container.RegisterType<ILoader, BarLoader>("bar"); 
container.RegisterType<ILoader, BazLoader>("baz"); 

var c = container.Resolve<MyConsumer>(); 

suponiendo que el MyConsumer constructor se define así:

public MyConsumer(ILoader[] loaders) 

Sin embargo, debe ser consciente de que (por alguna razón inexplicable) Unidad solo incluye llamados componentes de esta manera. El componentedefecto:

container.RegisterType<ILoader, Loader>(); 

se no ser incluido en la matriz, ya que no tiene nombre.

+0

wow, eso es una gran punta gracias –

+0

No exactamente insondable: la razón es que, si necesita más de una entrada para el mismo tipo, entonces debe agregar un nombre de lo contrario la unidad va a pensar que en realidad estás anulando la entrada anterior (que está prohibida). –

+3

@BrunoBrant 'insondable' porque ningún otro contenedor DI funciona así. Ver p. [mi libro] (http://amzn.to/12p90MG) para más detalles. –

3

El uso de Resolve durante el "tiempo de configuración" es aceptable y, a menudo, útil, y es perfectamente válido para matrices o enumerables.

También podría haber hecho lo anterior registrando el tipo ILoader[] y registrando cada uno de los tipos específicos ILoader usando la sobrecarga RegisterType que toma un nombre.

Luego, donde sea necesario ILoader[] (por ejemplo, debe inyectarse), todo lo anterior se resolverá por usted después del tiempo de configuración. Por supuesto, si necesita múltiple/diferente ILoader[], volvería a necesitar usar Resolve durante el tiempo de configuración.

1

Si tiene un escenario un poco más complicado en el que se deben usar diferentes matrices de valores en diferentes lugares, entonces puede usar ResolvedArrayParameter, p. Ej.

container.RegisterType<ILoader, FooLoader>("foo"); 
container.RegisterType<ILoader, BarLoader>("bar"); 
container.RegisterType<ILoader, BazLoader>("baz"); 
container.RegisterType<ILoader, BooLoader>("boo"); 

container.RegisterType<IConsumer, MyConsumer>("c1", 
    new InjectionConstructor(
     new ResolvedArrayParameter<ILoader>(
      new ResolvedParameter<ILoader>("foo"), 
      new ResolvedParameter<ILoader>("bar")))); 

container.RegisterType<IConsumer, MyConsumer>("c2", 
    new InjectionConstructor(
     new ResolvedArrayParameter<ILoader>(
      new ResolvedParameter<ILoader>("baz"), 
      new ResolvedParameter<ILoader>("boo")))); 

var c1 = container.Resolve<MyConsumer>("c1"); 
var c1 = container.Resolve<MyConsumer>("c2"); 
Cuestiones relacionadas