2014-06-20 12 views
10

Mam dekorator, który ma kilka innych zależności, które powinny zostać rozwiązane za pomocą kontenera. Przykład:Zarejestruj dekoratora w autofac bez ręcznego określania wszystkich zależności

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

mogę zarejestrować to tak:

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

To działa, ale nie tak ładne, że muszę ręcznie określić wszystkie inne zależności. Co chciałbym zrobić, to:

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

Jeżeli IFoo zostanie rozwiązany do „wewnętrzna” IFoo i inne zależności zostały rozwiązane z pojemnika. Czy to możliwe, czy mogę zarejestrować dekorator za pomocą Func, który spowoduje to zachowanie?

Odpowiedz

8

Aby uniknąć ręcznego określania wszystkich zależności, należy zarejestrować dekorator w Autofac i rozwiązać go w ramach pierwszego parametru metody 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>(); 

Rejestracja dekoratora przy użyciu nazwanej rejestracji pozwoli uniknąć konfliktów.

+0

To jest niesamowite, ale co jeśli nie wiesz (lub nie obchodzi), że konkretna implementacja 'IFoo' to' Foo'? Czy można zadeklarować coś podobnego do tego, jak "udekorować wszystko, co obecnie rozwiązuje" IFoo "za pomocą' FooDecorator'? (zakładając, że IFoo był wcześniej zarejestrowany, by dostarczyć 'IFoo', ale niekoniecznie jako _named_serwer) - PS Myślę, że to jest to, czego szukał OP, także –

+0

@CristiDiaconescu nie ma łatwego rozwiązania, aby to zrobić i bez określania nazwanego pierwszy dekorator będziesz mieć 2 rejestracje w kontenerze Autofac. Jeśli chcesz uzyskać więcej informacji na temat tego, jak osiągnąć to, co chcesz, możesz zadać nowe pytanie. –

1

podstawie odpowiedzi Cyril Durand, oto jest ogólną metodą pomocnik zarejestrować dekorator:

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

Jeśli wymagane są więcej niż jeden zagnieżdżone dekoratorzy podobny sposób z kilku parametrów ogólnych (TDecorator1, TDecorator2 etc) można wprowadzić.

Powiązane problemy