Malik Amurlayev
Malik Amurlayev

Reputation: 2608

IoC/DI: How to inject specific instance when there are multiple implementations of same interface

Assume we have two implementations of IService interface:

public interface IService { }

public class Service1 : IService { }

public class Service2 : IService { }

Then we have two classes which are depended on IService:

public class Consumer1
{
    public Consumer1(IService svc) { }
}

public class Consumer2
{
    public Consumer2(IService svc) { }
}

Now, how can I inject Service1 into Consumer1 and Service2 into Consumer2 using Simple Injector as dependency container and without using a factory or separate interfaces?

The generic pattern (not related to specific DI container) of how to archive this would be also great :)

UPDATE
I've already tried the context based injection with Simple Injector. The documentation is very limited and I'm ended up with the following code:

container.RegisterConditional(
    typeof(IService),
    typeof(Service1),
    Lifestyle.Transient,
    c => c.Consumer.ImplementationType == typeof(Consumer1));

container.RegisterConditional(
    typeof(IService),
    typeof(Service2),
    Lifestyle.Transient,
    c => c.Consumer.ImplementationType == typeof(Consumer2));

container.Register<Consumer1>();
container.Register<Consumer2>();

but then I get an exception

The configuration is invalid. Creating the instance for type Consumer1 failed. The constructor of type Consumer1 contains the parameter with name 'svc' and type IService that is not registered. Please ensure IService is registered, or change the constructor of Consumer1. 1 conditional registration for IService exists that is applicable to IService, but its supplied predicate didn't return true when provided with the contextual information for Consumer1.

I've tried with different variations of predicate but without success...

c => c.Consumer.Target.TargetType == typeof(Consumer1)
c => c.Consumer.ServiceType == typeof(Consumer1)

Upvotes: 1

Views: 1149

Answers (1)

qujck
qujck

Reputation: 14580

I'm unable to reproduce this problem with the latest version (3.1) of SI. This test passes:

[Test]
public void Test1()
{
    var container = new Container();

    container.RegisterConditional<IService, Service1>(
        c => c.Consumer.ImplementationType == typeof(Consumer1));
    container.RegisterConditional<IService, Service2>(
        c => c.Consumer.ImplementationType == typeof(Consumer2));
    container.Register<Consumer1>();
    container.Register<Consumer2>();

    container.Verify();

    var result1 = container.GetInstance<Consumer1>();
    var result2 = container.GetInstance<Consumer2>();

    Assert.IsInstanceOf<Service1>(result1.Svc);
    Assert.IsInstanceOf<Service2>(result2.Svc);
}

What version of SI are you using and are you sure you are using the correct instance of the container?

Upvotes: 1

Related Questions