views:

168

answers:

2

How to use single component for multiple services in Unity Framework?

In Windsor it is configured in the following way:

var container = new WindsorContainer();
container.Register(Component.For<Service1, Service2>()
                            .ImplementedBy<Component>());

var service1 = container.Resolve<Service1>();
var service2 = container.Resolve<Service2>();

The idea with forwarded types is that if the component is a singleton service1 and service2 are the same instance.

A: 

AFAIK, you can't: you have to register each service with the same mapped component:

container.RegisterType<Service1, Component>(new ContainerControlledLifetimeManager())
         .RegisterType<Service2, Component>(new ContainerControlledLifetimeManager())
onof
wow, that's pretty unintuitive
Krzysztof Koźmic
Does it really do forwarded types? Or registers two separate components. See updated question.
Krzysztof Koźmic
This answer results in two different instances when you resolve Service1 and Service2 because the default lifetime in Unity is Transient.
Mark Seemann
Yes it resulted in two different instances. Singleton lifetime needed
onof
+2  A: 

This test passes:

[Fact]
public void ContainerCorrectlyForwards()
{
    var container = new UnityContainer();
    container.RegisterType<IService1, MyComponent>(
        new ContainerControlledLifetimeManager());
    container.RegisterType<IService2, MyComponent>(
        new ContainerControlledLifetimeManager());

    var service1 = container.Resolve<IService1>();
    var service2 = container.Resolve<IService2>();

    Assert.Same(service1, service2);
}
Mark Seemann
Thank you! But did you know that test will pass even if you remove ContainerControlledLifetimeManager() for IService1 or IService2? Who decided that ContainerControlled will override Transient lifetime (for components with the same names - default name in our case)?
Rationalle
That is indeed surprising. I have no good explanation for that. In fact, I'd be tempted to log that as a bug...
Mark Seemann
With Unity 1.2 that test fails without ContainerControlledLifetimeManager
onof
... and fails with Unity 2.0, too, without ContainerControlledLifetimeManager.
onof
@onof: Yes, but Rationalle's point was that if you remove only *one of them* it still succeeds. I have verified this for Unity 2, but not 1.2.
Mark Seemann
ahh.. sorry. Anyway it succeeds in 1.2 too. weird
onof
There is a reason for this behavior. It's up to you to decide if it's a good reason. :-) The lifetime manager and injection members are applied to the IMPLEMENTATION type. Since you're using the same implemementation type, the last one wins. However, if you don't specify a lifetime manager, it doesn't supply a new Transient one - instead one springs into existence the first time you request the type and there isn't one specified.
Chris Tavares
(Ran out of room). Anyway, the code above is equivalent to: container.RegisterType<IService1, MyComponent>().RegisterType<IService2,MyComponent>().RegisterType<MyComponent>(new ContainerControlledLifetimeManager());
Chris Tavares