gpt4 book ai didi

c# - 统一: resolve class with two implementations of one interface

转载 作者:行者123 更新时间:2023-11-30 21:51:41 24 4
gpt4 key购买 nike

我的结构如下:

static void Main(string[] args) {
var container = new UnityContainer();
container.RegisterType<IBaseService, ServiceA>("a");
container.RegisterType<IBaseService, ServiceB>("b");
container.RegisterType<IWorker, Worker>();

var runner = container.Resolve<Runner>();
/* ... */
}

public class Runner {
public Runner(IWorker worker) {}

}

public class Worker : IWorker {
public Worker(IBaseService a, IBaseService b) { /* ... */ }
}

public class ServiceA : IBaseService {}
public class ServiceB : IBaseService {}

我知道我可以为 ServiceA 设置额外的接口(interface),例如 IServiceA(对于 ServiceB - IServiceB 也是如此),并将它们注册到容器中。但是,是否可以使用具有相同契约(Contract) IBaseService 的两个服务来解析 Worker 的实例(第一个参数应获得 ServiceA,第二个参数应获得 ServiceB),否则会导致某种歧义?

最佳答案

如果您尝试运行发布的代码,您将收到异常:

The current type, IBaseService, is an interface and cannot be constructed. Are you missing a type mapping?

这是因为容器中没有为IBaseService注册默认注册(默认意思是没有名字)。仅注册了两个命名接口(interface)映射。

处理这种情况的方法很少。正如@Haukinger 所提到的,一种方法是将所有 IBaseService 实现注入(inject)到对象中。

所以你可以这样声明你的类:

public class Worker2 : IWorker
{
public Worker2(IEnumerable<IBaseService> baseServices)
{
/* ... */
}
}

然后像这样向容器注册:

container.RegisterType(typeof(IEnumerable<IBaseService>), typeof(IBaseService[]));

这映射了一个 IEnumerable<IBaseService>IBaseService 的数组这是有效的,因为当 Unity 看到一个数组时,它会注入(inject)使用所有 named 注册并将它们注入(inject)到对象中。您也可以在没有 IEnumerable 映射的情况下直接使用数组。

这种方法可能很有用,但通常您想知道注入(inject)的是哪种类型(例如,必须在运行时根据其他一些标准选择正确实现的工厂)。

另一种方法是配置 Unity 以将正确命名的注册注入(inject)到 Worker 中:

container.RegisterType<IWorker, Worker>(
new InjectionConstructor(
new ResolvedParameter<IBaseService>("a"),
new ResolvedParameter<IBaseService>("b")));

在上面的例子中,我们告诉 Unity 使用什么构造函数以及注入(inject)哪个实现。

另一种方法是使用 InjectionFactory:

container.RegisterType<IWorker, Worker>(
new InjectionFactory(
c => new Worker(c.Resolve<IBaseService>("a"), c.Resolve<IBaseService>("b"))
));

使用 InjectionFactory 的一个好处是,因为我们正在更新 Worker 对象,所以我们可以让编译器检查构造函数。例如如果更改 Worker 构造函数以添加新参数,则会出现编译错误。相反,InjectionConstructor 方法可以编译但会生成运行时错误 System.InvalidOperationException: The type Worker does not have a constructor that takes the parameters (IBaseService, IBaseService).

关于c# - 统一: resolve class with two implementations of one interface,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35397301/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com