注册
|
登录
发帖
热搜
活动
交友
discuz
论坛
BBS
翼度工具
翼度网址导航
开发工具
Linux命令速查
网页设计配色表
在线制作icon
颜色代码选取器
翼度科技
»
论坛
›
编程开发
›
python
›
查看内容
返回列表
发新帖
.NET依赖注入之一个接口多个实现
湿水不易破
湿水不易破
当前离线
积分
12
4
主题
4
帖子
12
积分
新手上路
新手上路, 积分 12, 距离下一级还需 38 积分
新手上路, 积分 12, 距离下一级还需 38 积分
积分
12
发消息
显示全部楼层
前言
最近又在项目中碰到需要将原本单实现的接口改造成多个实现的场景,这里记录一下常见的几种改法。
假设已经存在如下接口ICustomService和其实现CustomService,由于只有一种实现,注入和使用非常容易。
public interface ICustomService
{
void MethodA();
void MethodB();
}
public class CustomService: ICustomService
{
public void MethodA()
{
}
public void MethodB()
{
}
}
//注入
builder.Services.AddTransient<ICustomService, CustomService>();
//使用
private readonly ICustomService _customService;
public CustomController(ICustomService customService)
{
_customService = customService;
}
复制代码
现在我们需要增加一种实现。
使用多个接口实现
我们可以将原ICustomService内的方法移到到一个新的基接口,共享出来,需要多少个实现,就创建多少个空接口继承该基接口。
//基接口
public interface ICustomBaseService
{
void MethodA();
void MethodB();
}
//多个空接口
public interface ICustomService : ICustomBaseService
{
}
public interface ICustomServiceV2 : ICustomBaseService
{
}
//第一种实现
public class CustomService: ICustomService
{
public void MethodA()
{
}
public void MethodB()
{
}
}
//第二种实现
public class CustomServiceV2: ICustomServiceV2
{
public void MethodA()
{
}
public void MethodB()
{
}
}
//注入
builder.Services.AddTransient<ICustomService, CustomService>();
builder.Services.AddTransient<ICustomServiceV2, CustomServiceV2>();
//使用
private readonly ICustomService _customService;
private readonly ICustomServiceV2 _customServiceV2;
public CustomController(ICustomService customService,ICustomServiceV2 customServiceV2)
{
_customService = customService;
_customServiceV2 = customServiceV2;
}
复制代码
这种实现方式需要增加了一套空接口做隔离,看似可能比较“浪费”,但后期随着项目的演进,ICustomService和ICustomServiceV2可能会慢慢分化,我们可以很方便的为它们扩充各种独有方法。
使用单接口实现
如果我们确定不要要多个接口,也可以使用下面的单接口实现
public interface ICustomService
{
void MethodA();
void MethodB();
}
//第一种实现
public class CustomService: ICustomService
{
public void MethodA()
{
}
public void MethodB()
{
}
}
//第二种实现
public class CustomServiceV2: ICustomService
{
public void MethodA()
{
}
public void MethodB()
{
}
}
//注入
builder.Services.AddTransient<ICustomService, CustomService>();
builder.Services.AddTransient<ICustomService, CustomServiceV2>();
//使用
private readonly ICustomService _customService;
private readonly ICustomService _customServiceV2;
public CustomController(IEnumerable<ICustomService> customServices)
{
_customService = customServices.ElementAt(0);
_customServiceV2 = customServices.ElementAt(1);
}
复制代码
从上面代码可以看到,我们是为从接口ICustomService注册两个实现,并从IEnumerable解析出了这两个实现。这里可能会有两个疑问
为什么第一个实现CustomService没有被第二个实现CustomServiceV2替换掉?
为什么可以从IEnumerable解析到我们需要的服务?
答案在
Microsoft.Extensions.DependencyInjection.ServiceDescriptor
和
Microsoft.Extensions.DependencyInjection.ServiceCollection
这两个类里,进程里,依赖注入的服务,会被添加到ServiceCollection里,ServiceCollection是一组ServiceDescriptor的集合,ServiceDescriptor通过服务类型、实现以及生命周期三个组合在一起构成的标识来确定服务。而ICustomService+CustomService+Transient和ICustomService+CustomServiceV2+Transient是两个不同的ServiceDescriptor,因此不会被替换。同时服务类型的ServiceDescriptor会被聚合在一起,于是我们可以很方便的从IEnumerable对象中解析出所有的同类型的服务。
总结
本质上,两种方法都是多态性(Polymorphism)的应用,没有优劣之分,根据场景选择合适的写法。
链接
https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection
https://github.com/dotnet/runtime
来源:
https://www.cnblogs.com/netry/archive/2023/02/26/net-dependency-injection-multiple-implementations.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
上一篇:
odoo 给form表单视图内联列表添加按钮
下一篇:
Python批量绘制遥感影像数据的直方图
发表于 2023-2-26 21:47:30
举报
回复
使用道具
分享
返回列表
发新帖
本版积分规则
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
快速回复
快速回复
返回顶部
返回顶部
返回列表
返回列表