首页 文章

IoC/DI:当有多个相同接口的实现时,如何注入特定实例

提问于
浏览
1

假设我们有两个IService接口的实现:

public interface IService { }

public class Service1 : IService { }

public class Service2 : IService { }

然后我们有两个依赖于IService的类:

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

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

现在,我如何使用简单的注射器作为依赖容器将Service1注入Consumer1Service2 Consumer2而不使用工厂或单独的接口****?

如何存档这个通用模式(与特定的 DI 容器无关)也很棒:)

更新
我已经尝试过使用 Simple Injector 进行基于上下文的注入。文档非常有限,我最终得到以下代码:

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>();

但后来我得到了一个例外

配置无效。为 Consumer1 类型创建实例失败。 Consumer1 类型的构造函数包含名称为“svc”的参数,并且类型为未注册的 IService。请确保 IService 已注册,或更改 Consumer1 的构造函数。存在 1 个适用于 IService 的 IService 条件注册,但当提供 Consumer1 的上下文信息时,其提供的谓词未返回 true。

我尝试过不同的谓词变体,但没有成功......

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

1 回答

  • 1

    我无法使用 SI 的最新版本(3.1)重现此问题。该测试通过:

    [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);
    }
    

    您使用的是什么版本的 SI,并且您确定使用的是正确的container实例吗?

相关问题