RegisterMultiple does not keep implementation type as singleton if registered as multiple registration types?

187 views Asked by At

I am trying to add a type called TypeA as two different registration types: InterfaceA and InterfaceB.

container.RegisterMultiple(typeof(InterfaceA), new[] {typeof(TypeA), typeof(TypeB)});
container.RegisterMultiple(typeof(InterfaceB), new[] {typeof(TypeA), typeof(TypeC)});

But when I Resolve them, I get one instance of TypeA when resolving InterfaceA, and another instance when resolving InterfaceB. I expect to get the same instance for both resolves, but I am not.

I have also tried to add .AsSingleton() to the call, but it made no difference.

Am I doing something wrong, or does anyone have any ideas of doing this without adding a TypeAFactory or such that keeps track of the instances instead?

Thanks in advance for any help.

2

There are 2 answers

1
Christian Horsdal On

I think what you are seeing is by design.

To get the same instance for both interfaces you can create the instance yourself and register it for both interfaces:

var instanceOfA = new TypeA(...);
container.Register<InterfaceA>(instanceOfA);
container.Register<InterfaceB>(instanceOfA);
1
Stmated On

I solved this on my own with a quite ugly (but yet quite elegant) solution.

I create another, internal, instance of a TinyIoCContainer, and I register all my types with the actual TinyIoCContainer.Current by giving it a factory in the form of:

var container = TinyIoCContainer.Current;
var internalIoC = new TinyIoCContainer();
Dictionary<Type, Object> instances = new Dictionary<Type, Object>();

...

Func<TinyIoCContainer, NamedParameterOverloads, Object> factory = (TinyIoCContainer c, NamedParameterOverloads o) =>
{
    if (instances.ContainsKey(implementationType) == false)
    {
        // Create the instance only once, and save it to our dictionary.
        // This way we can get singleton implementations of multi-registered types.
        instances.Add(implementationType, internalIoC.Resolve(implementationType));
    }

    return instances[implementationType];
};

container.Register(registerType, factory, implementationType.FullName);

I'm sure there will be a few caveats with this solution, but I'm also sure I'll be able to figure out a workable fix for them, as things look right now.