Register implementation as singleton and as decorator

Jun 14, 2013 at 4:45 PM
Is it possible to register a class as singleton and at the same time as decorator for one of the implemented interfaces?

Consider these types:
    public interface IService { }

    public interface IAdvancedService : IService { }

    public interface IService2 { }

    public class Service : IService { }

    public class AdvancedService: IAdvancedService, IService2
    {
        public AdvancedService(IService service) { }
    }
I want to register AdvancedService as a singleton for IService2 and IAdvancedService. Additionally, I want it to be a decorator for IService. But even in the decorator case the exact same instance should be returned as for the other services.

The expected result would be that all of the following asserts don't fail:
Assert.Same(container.GetInstance<IService>(), container.GetInstance<IService2>());
Assert.Same(container.GetInstance<IService>(), container.GetInstance<IAdvancedService>());
Assert.Same(container.GetInstance<IService2>(), container.GetInstance<IAdvancedService>());
I was unable to achieve this.
I tried like so:
container.Register<IService2, IAdvancedService, AdvancedService>(Lifestyle.Singleton);
container.RegisterSingleDecorator(typeof(IService), typeof(AdvancedService));
Coordinator
Jun 14, 2013 at 5:01 PM
I'm trying to get my head around what you're trying to achieve. Without a container, is this what you're looking for?
var s = new Service();
var a = new AdvancedService(service);

IService service = a;
IAdvancedService advanced = a;
IService2 service2 = a;
Jun 14, 2013 at 5:05 PM
Exactly. Except that Service and AdvancedService both have additional dependencies in the real code.
Coordinator
Jun 14, 2013 at 5:24 PM
Edited Jun 14, 2013 at 5:25 PM
In that case, this should do the trick:
container.RegisterSingle<IService, Service>();
container.RegisterSingleDecorator(typeof(IService), typeof(AdvancedService));

container.RegisterSingle<IAdvancedService>(
    () => (IAdvancedService)container.GetInstance<IService>());
container.RegisterSingle<IService2>(
    () => (IService2)container.GetInstance<IService>());
Marked as answer by dot_NET_Junkie on 3/2/2014 at 10:30 AM
Jun 14, 2013 at 5:30 PM
Yep, that worked. Thanks! :-)