3
votes

I have the following scenario:

In the base container, I am registering a type.

container.RegisterType<IFoo,Foo>();

In a child container I would like to register a Decorator which wraps whatever the base container uses. So if I have this class:

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

I want to register:

childContainer.RegisterType<IFoo,FooDecorator>();

It would seem reasonable to me that when the child container resolves IFoo in the FooDecorator constructor, it will try to resolve the parent container's IFoo. But it doesn't. It tries to resolves FooDecorator again, and therefore again and again until a StackOverflow exception is raised.

I know this can be solved by specifying an InjectionConstructor in the child container registration, like this:

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

But this seems fragile. If someone wants to change the actual instance of IFoo in the base container from Foo to something else, he would have to also modify all the child containers as well.

So am I missing something? Is there a better solution to the problem?

2

2 Answers

4
votes

You can use named mapping:

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

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

This way the registration of the decorator depends on the named mapping "decorated" of the interface IFoo.

1
votes

onof's answer requires fiddling with constructor parameters, that may change during development. My answer elsewhere addresses this but has different drawbacks in exchange.

With my technique the registration would look as follows:

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