Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unity: Registering the same type for two interfaces

I'm seeing a weird behaviour in the Unity container, when working with two interfaces, that both register to the same decorator. A code example will be clearer.

I have the following class hierarchy:

   public interface IBaseInterface
    {

    }

    public interface IInterface1: IBaseInterface
    {

    }
    public interface IInterface2: IBaseInterface
    {

    }
    public class Interface1Impl : IInterface1
    {
    }
    public class Interface2Impl : IInterface2
    {
    }

    public class BaseInterfaceDecorator: IInterface1,IInterface2
    {
        private readonly IBaseInterface baseInterface;

        public BaseInterfaceDecorator(IBaseInterface baseInterface)
        {
            this.baseInterface = baseInterface;
        }
    }

    public class MyClass
    {
        private readonly IInterface1 interface1;

        public MyClass(IInterface1 interface1)
        {
            this.interface1 = interface1;
        }            
    }

And this is the registration code:

var container = new UnityContainer();           
        container.RegisterType<IInterface1, BaseInterfaceDecorator>(
            new InjectionConstructor(
                new ResolvedParameter<Interface1Impl>()));

        container.RegisterType<IInterface2, BaseInterfaceDecorator>(
           new InjectionConstructor(
               new ResolvedParameter<Interface2Impl>()));


        var dependency = container.Resolve<MyClass>();

When resolving MyClass I'm getting a BaseInterfaceDecorator with Interface2Impl instead of Interface1Impl. Seems strange to me. Can you explain?

like image 521
Doron Yaacoby Avatar asked Jan 17 '11 13:01

Doron Yaacoby


2 Answers

It looks like the last injection instruction for a given "to" type wins. If you grab a copy of Reflector and take a look at the UnityContainer.RegisterType(Type, Type, string, LifetimeManager, InjectionMember[]) implementation, you'll see why.

IMO, this behaviour is a bug. At the very least, InjectedMembers.ConfigureInjectionFor(Type, string, InjectionMember[]) should throw an exception instead of silently replacing the previous injection configuration. However, it really ought to support what you are attempting.

like image 192
Nicole Calinoiu Avatar answered Nov 06 '22 14:11

Nicole Calinoiu


I don't know if it helps. It's most likely too late for you by now. But, this is achievable if you use named registration, i.e. you register each type to be resolved with a different name.

For example:

Container.RegisterType<IInterface1, BaseInterfaceDecorator>("interface1");
Container.RegisterType<IInterface2, BaseInterfaceDecorator>("interface2");
like image 35
Bill Richards Avatar answered Nov 06 '22 15:11

Bill Richards