tags:

views:

435

answers:

3

Hi all, how do I register two different interfaces in Unity with the same instance... Currently I am using

        _container.RegisterType<EventService, EventService>(new ContainerControlledLifetimeManager());
        _container.RegisterInstance<IEventService>(_container.Resolve<EventService>());
        _container.RegisterInstance<IEventServiceInformation>(_container.Resolve<EventService>());

which works, but does not look nice..

So, I think you get the idea. EventService implements two interfaces, I want a reference to the same object if I resolve the interfaces.

Chris

+1  A: 

Edit

After some feedback in the comments I've decided that Sven's answer is a much superior answer. Thanks to Chris Tavares for pointing out the technical merits.


That's pretty much the only way to do it.

You could modify it slightly (I hate RegisterType with the same type for each generic parameter):

EventService es = _container.Resolve<EventService>();
_container.RegisterInstance<IEventService>(es);
_container.RegisterInstance<IEventServiceInformation>(es);

If one or more of your IoC children is going to request the concrete EventService type (hopefully not) you'd add one more RegisterInstance of type RegisterInstance<EventService>. Hopefully you don't need that and all of the dependent objects are asking for an IEventService, rather than an EventService.

Hope this helps, Anderson

Anderson Imes
It is good practice with dependency injection, to separate wiring time from resolution time as much as possible. This solution has the drawback is that it requires you to mix calls to 'resolve' with calls to 'register'
Nigel Thorne
@Nigel Thorne: Generally that is true, but in this case the OP had a service he/she needed to register that had a lot of dependencies. I suggested Unity to create this object so that those dependencies were automatically resolved so that the instance could be used for both Register calls (he/she needed the very same instance returned for either interface). Normally this is undesirable, but really the only way to do this in this case (other than instantiating the object manually).
Anderson Imes
This is really not the way to go - use Sven Kunzler's answer below instead.
Chris Tavares
@Chris Tavares I agree I like his better. However, I'd be hard-pressed to say my answer is *wrong*.
Anderson Imes
@Anderson - well, this approach does work, but it has two undesirable side effects. First, two RegisterInstance calls result in two lifetime managers, which means that Dispose will be called twice on the object. That may or may not be a problem depending on the type.The other issue is this: what if EventService itself has dependencies? In that case, you can't do the Resolve call until after you're sure all EventService's dependencies are registered in the container. With the RegisterType approach, you can register it whenever you want.
Chris Tavares
@Chris Tavares: I wasn't aware of the first problem and as for the second, that's exactly why I would use Sven's approach over mine... I've run into that very problem, you are correct.
Anderson Imes
@Chris Tavares: I've updated my answer to refer to Sven's as the preferred answer. Thanks for taking the time to comment on this. Lots of people will benefit from reading this.
Anderson Imes
A: 

I had the same issue, and decided the best solution was a slight design change. Could you not merge interfaces, and resolve by that?

interface IEventServiceHolder : IEventService, IEventServiceInformation
{
}

class EventService : IEventServiceHolder
{
   .. yadda yadda .. 
}

Then simply register it once:

container.RegisterType<IEventServiceHolder>();

and resolve

var k = container.Resolve<IEventServiceHolder>();
Joe Hartrick
+2  A: 

A little late an answer, but should do the trick:

_container.RegisterType<EventService>(new ContainerControlledLifetimeManager());
_container.RegisterType<IEventService, EventService>();
_container.RegisterType<IEventServiceInformation, EventService>();

bool singleton = ReferenceEquals(_container.Resolve<IEventService>(), _container.Resolve<IEventServiceInformation>());
Sven Künzler