Mapping 2 interfaces to the same singleton instance.

Oct 13, 2008 at 8:34 AM

Is it possible with Unity to rigister in the container associations of two different interfaces to one singleton instance? I have a class implementing both interfaces but I would like it to be a singleton when accessing from both interfaces. Is it possible with Unity?

Oct 13, 2008 at 6:18 PM
container.RegisterType<MySingletonType>(new ContainerControlledLifetimeManager())
    .RegisterType<IInterfaceOne, MySingletonType>()
    .RegisterType<IInterfaceTwo, MySingletonType>();

Or the corresponding thing in the config file.

Dec 10, 2008 at 11:03 PM
Sorry, I think I may have misunderstood the way this works. I found out today you can't reuse a lifetime manager.

So if I write:

  container.RegisterType<IFoo, Foo>(new ContainerControlledLifetimeManager())
    .RegisterType<IBar, Bar>();

then IBar instances will also be singletons?

And if I broke the above into two lines (container.Register... and container.Register...) then only IFoo instances would be singletons?

Bill Sorensen
Dec 11, 2008 at 12:01 AM
No, the IBar instance would be transient.

The lifetime manager applies to the concrete type that's being registered. So in my call stack above, MySingletonType is set as container controlled.

The type mapping for the interfaces is a separate piece of configuration, that's done in one spot for convenience. Notice above that both IInterfaceOne AND IInterfaceTwo were mapped to MySingletonType. Since MySingletonType is set as a singleton, you'll get the same instance for a request for either interface.

With your call with IFoo and IBar, you've mapped IFoo to Foo, set Foo to ContainerControlledLifetimeManager, and mapped IBar to Bar. You haven't said anything about the lifetime of Bar itself, so that remains transient.

I could have saved a line above by doing:

container.RegisterType<IInterfaceOne, MySingletonType>(new ContainerControlledLifetimeManager())
    .RegisterType<IInterfaceTwo, MySingletonType>();

but I was trying to avoid exactly the confusion you ended up with. Oh well, can't win 'em all.

Anyway, the important thing here is that the lifetime manager is applied to the concrete type, not the interface.

Does that help?


Dec 11, 2008 at 6:46 PM
Thanks - that's the way I thought it worked in the first place (principle of least astonishment). I missed that you used the same concrete type in the registrations.

In the case I had, I wanted to register two different concrete types as singletons. My initial attempt was:

  LifetimeManager singleton = new ContainerControlledLifetimeManager();

  container.RegisterType<IFoo, Foo>(singleton)
    .RegisterType<IBar, Bar>(singleton);

which raises an exception. Apparently LifetimeManagers cannot be reused, resulting in the less intuitive (for me) syntax:

  container.RegisterType<IFoo, Foo>(new ContainerControlledLifetimeManager())
    .RegisterType<IBar, Bar>(new ContainerControlledLifetimeManager());

Is this correct?

Thanks again,
Bill Sorensen
Dec 11, 2008 at 7:50 PM
Yes, that is correct. Lifetime managers cannot be reused, so you need to new up one for each registration.