2014-06-20 6 views
10

Ho un decoratore che ha alcune altre dipendenze che dovrebbero anche essere risolti usando il contenitore. Esempio:Registrare un decoratore in autofac senza specificare manualmente tutte le dipendenze

public class FooDecorator : IFoo 
{ 
    public FooDecorator(IFoo inner, IBar bar, IBaz baz) 
} 

posso registrare questo come questo:

builder.RegisterType<Foo>().As<IFoo>(); 
builder.RegisterDecorator<IFoo>((c, inner) => 
    new FooDecorator(inner, c.Resolve<IBar>(), c.Resolve<IBaz>()), "key"); 

Questo è il lavoro, ma non così bella che devo specificare manualmente tutte le altre dipendenze. Quello che vorrei fare è:

builder.RegisterDecorator<FooDecorator, IFoo>("key"); 

Qualora il IFoo viene risolto il 'interiore' IFoo e le altre dipendenze sono risolte dal contenitore. È possibile, o posso registrare un decoratore con un Func che si tradurrà in questo comportamento?

risposta

8

Per evitare di specificare tutte le dipendenze manualmente, è necessario registrare il decoratore nel Autofac e risolvere all'interno del primo parametro del metodo RegisterDecorator.

builder.RegisterType<Foo>() 
     .Named<IFoo>("original"); 
builder.RegisterType<FooDecorator>() 
     .Named<IFoo>("decorator"); 
builder.RegisterDecorator<IFoo>((c, inner) => c.ResolveNamed<IFoo>("decorator", TypedParameter.From(inner)), "original") 
     .As<IFoo>(); 

La registrazione del decoratore utilizzando la registrazione con nome eviterà qualsiasi conflitto.

+0

Questo è fantastico, ma cosa succede se non si conosce (o si cura) che l'implementazione specifica di 'IFoo' è' Foo'? È possibile dichiarare qualcosa sulla falsariga di "decorare ciò che attualmente risolve in" IFoo' con 'FooDecorator'"? (supponendo che IFoo sia stato precedentemente registrato per fornire 'IFoo', ma non necessariamente come servizio _named_) - PS Penso che questo sia quello che cercava l'OP, anche –

+0

@CristiDiaconescu non c'è una soluzione facile da fare e senza specificare un nome per il primo decoratore avrai 2 registrazioni nel contenitore Autofac. Sentiti libero di fare una nuova domanda se vuoi ulteriori dettagli su come ottenere ciò che desideri. –

1

in base alla risposta di Cyril Durand, ecco un metodo di supporto generico per registrare un decoratore:

private void RegisterDecorator<TInterface, TImplementation, TDecorator>(ContainerBuilder builder) where TImplementation : TInterface where TDecorator : TInterface 
    { 
     builder.RegisterType<TImplementation>().Named<TInterface>("implementation"); 
     builder.RegisterType<TDecorator>().Named<TInterface>("decorator"); 
     builder.RegisterDecorator<TInterface>((c, inner) => c.ResolveNamed<TInterface>("decorator", TypedParameter.From(inner)), "implementation"); 
    } 

Se sono necessari più di un decoratori annidati, un metodo simile con più parametri generici (TDecorator1, TDecorator2 ecc) può essere introdotto