2011-04-10 62 views
3

我有以下情形:Unity:注册一个装饰器在儿童容器中

在基本容器中,我正在注册一个类型。

container.RegisterType<IFoo,Foo>(); 

在一个子容器中,我想注册一个包装基本容器使用的装饰器。所以,如果我有这个类:

public class FooDecorator: IFoo 
{ 
    public FooDecorator(IFoo foo) {} 
} 

我要注册:

childContainer.RegisterType<IFoo,FooDecorator>(); 

这似乎是合理的,我当孩子容器中FooDecorator构造解析的IFoo,它会尝试解析父容器的IFoo。但事实并非如此。它试图再次解析FooDecorator,并因此一次又一次地引发StackOverflow异常。

我知道这可以通过在子容器注册指定的InjectionConstructor,这样解决:

childContainer.RegisterType<IFoo,FooDecorator>(
    new InjectionConstructor(new ResolvedParameter<Foo>())); 

但这似乎脆弱。如果有人想将基本容器中IFoo的实际实例从Foo更改为其他内容,那么他​​也必须修改所有子容器。

所以我错过了什么?有没有更好的解决方案?

回答

4

您可以使用一个名为映射:

parentContainer.RegisterType<IFoo, Foo>("decorated"); 

childContainer.RegisterType<IFoo, FooDecorator>(
    new InjectionConstructor(new ResolvedParameter<IFoo>("decorated"))); 

这样装饰的注册取决于“饰”界面的IFoo的命名映射。

+0

呀,这其实目前我在做什么,但我不喜欢这种解决方案非常多,因为现在我要手动注册每种使用IFoo的类型,或者确保在每个子容器中注册IFoo,即使它不需要重写默认行为。 – 2011-04-18 09:37:31

+0

您可以使用相同的映射在父容器中注册两次IFoo:一个已命名的注册和一个默认的注册。 – onof 2011-04-18 11:10:50

+0

是的,我再次使用了一个解决方案,但似乎有点时髦。我想现在没有其他办法了。谢谢 – 2011-04-20 05:29:39

1

onof's answer需要处理构造函数参数,这些参数在开发过程中可能会改变。 My answer elsewhere解决这个问题,但交换中有不同的缺点。

用我的技术登记将如下所示:

unityContainer.RegisterType<IService, LoggedService<ProfiledService<Service>>>();