gpt4 book ai didi

c# - IoC 容器中的命名服务——一个坏主意?

转载 作者:太空狗 更新时间:2023-10-29 22:34:06 26 4
gpt4 key购买 nike

在组合容器时使用服务 key (或“命名服务”)似乎是个坏主意。

使用命名服务需要我们使用匹配的键来注释我们的构造函数参数(从而与容器耦合),或者为我们的每个服务执行额外的连接(从而从容器中失去很多自动化)。

例如,我目前有以下接口(interface),由以下类实现:

  • IListSerializer
    • CheckboxListSerializer
    • TreeViewListSerializer

我还有无数类依赖于其中一个或两个类。但是,据我所知,我应该引用 IListSerializer 作为我的依赖项而不是实现。这意味着我必须使用键/名称来区分它们,这就是它开始变得丑陋的地方。

我可以看到我的选择是以下之一:

  • 用键注释构造函数参数(依赖项)。与 IoC 容器相结合。
  • 在合成根中执行手动连接。添加重复膨胀。
  • 引用类而不是接口(interface)。似乎只是为了满足 IoC 容器而进行的黑客攻击。

有什么建议吗?

最佳答案

一般来说,在为 IoC 设计组件和服务时,里氏替换原则是一个非常有用的指南。如果一个服务的两个实现不能在运行时互换使用,那么这个服务就太笼统了,没有意义。在这种情况下,我会考虑使用类似 IListSerializer<T> 的东西如果这是您的选择。

但是,如果您想使用命名服务,则使用 Autofac 进行设置既简单又无干扰。

首先,用它的名字注册每个序列化器:

builder.RegisterType<CheckBoxListSerializer>()
.Named<IListSerializer>("checkBoxSerializer");
builder.RegisterType<TreeViewListSerializer>()
.Named<IListSerializer>("treeViewSerializer");

然后,添加一个全局可用的参数,该参数使用构造函数参数名称来选择正确的实现。我们可以用一个模块来做到这一点:

class NamedParameterResolutionModule<TService> : Module
{
Parameter _attachedParameter = new ResolvedParameter(
(pi, c) => pi.ParameterType == typeof(TService),
(pi, c) => c.ResolveNamed<TService>(pi.Name));

protected override void AttachToComponentRegistration(
IComponentRegistry registry,
IComponentRegistration registration)
{
registration.Preparing += (s, e) => {
e.Parameters = new[] { _attachedParameter }.Contact(e.Parameters);
};
}
}

像这样注册模块:

builder.RegisterModule<NamedParameterResolutionModule<IListSerializer>>();

然后组件将根据构造函数参数名称获得序列化程序:

class SomeComponent : ...
{
public SomeComponent(IListSerializer checkBoxSerializer) { ...
}

关于c# - IoC 容器中的命名服务——一个坏主意?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6667970/

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