13

Is there a way to register a single interface which is implemented by more than one concrete class using [simple-injector] and without using template interface?

say we have 2 classes MyClass1 and Myclass2 and both these classes are implementing IInterface1

Now using [simple-injector] we were not able to do this

container.Register<IInterface1, Myclass1>();
container.Register<IInterface1, Myclass2>();

converting existing interface to template interface is kinda a hard job on the existing codebase. Hoping there is some easier out there.

2 Answers 2

18

You can register multiple implementation of the same interface with using the RegisterCollection method (see documentation: Configuring a collection of instances to be returned)

So you need to write:

container.Collection.Register<IInterface1>(typeof(Myclass1), typeof(Myclass2));

And now Simple Injector can inject a collection of Interface1 implementation into your constructor, for example:

public class Foo
{
    public Foo(IEnumerable<IInterface1> interfaces)
    {
        //...
    }
}

Or you can explicitly resolve your IInterface1 implementations with GetAllInstances:

var myClasses = container.GetAllInstances<IInterface1>();
Sign up to request clarification or add additional context in comments.

4 Comments

Problem with SimpleInjector is, after registering multiple implementations for one interface, there is no way to specify which of the registered instances should be returned for a given interface. At your sample, you cannot specify to return an instance of class Myclass2 when asking for IInterface1. Other IoC containers like Ninject allows to "name" each registration for the same service (interface), so you can disambiguate later at resolution time.
@Lester: If you need this, make sure you're not violating the Liskov Substitution Principle if you need this. But either way, here's more information about using keyed registration in Simple Injector.
@nemesv what if we need one implementation at a time e.g. Shoper class constructor has ICreditCard interface. And 2 classes MasterCard and VisaCard classes implement ICreditCard. Shoper needs one class at a time. How to use IOC i this scenario?
Use a factory pattern to solve the above problem (comment above not the answer). So, create a factory, inject that and get that to return an implementation based on whatever logic you need.
0

I was faced with the same issue. I found a workaround, you can select the implementation depending on the consumer (I wish it were the other way around!). See the example below:

container.RegisterConditional<IInterface1, Myclass1>(
            c => c.Consumer.ImplementationType == typeof(Myclass2Service));
container.RegisterConditional<IInterface1, Myclass2>(
            c => c.Consumer.ImplementationType == typeof(Myclass2Service));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.