C# 如何使用反射在ASP.NET核心中使用自己的接口注册多个实现?
我不熟悉ASP.NET Core 3.1中的依赖项注入,我正在尝试使用反射创建我的存储库类的单例实例,但我无法让它工作 目前,C# 如何使用反射在ASP.NET核心中使用自己的接口注册多个实现?,c#,asp.net-core,reflection,dependency-injection,C#,Asp.net Core,Reflection,Dependency Injection,我不熟悉ASP.NET Core 3.1中的依赖项注入,我正在尝试使用反射创建我的存储库类的单例实例,但我无法让它工作 目前,BookService使用DI中的BookRepository: 公共类图书服务:IBookService { 私有只读IBookRepository\u图书存储库; 公共图书服务(IBookRepository bookRepository) { _bookRepository=bookRepository; } 公共异步任务GetById(字符串id) { var f
BookService
使用DI中的BookRepository
:
公共类图书服务:IBookService
{
私有只读IBookRepository\u图书存储库;
公共图书服务(IBookRepository bookRepository)
{
_bookRepository=bookRepository;
}
公共异步任务GetById(字符串id)
{
var find=await\u bookRepository.FindAsync(id);
返回查找;
}
}
这是因为我向容器中添加了一个单例服务,代码如下():
services.AddSingleton()代码>
我试图通过反射来达到同样的效果
BookRepository
公共类BookRepository:BaseRepository,IBookRepository
{
}
IBookRepository
公共接口IBookRepository:IAsyncRepository
{
}
这就是我到目前为止所做的:
// Get all classes implementing IAsyncRepository
var repositoryTypes = assembly.GetTypes()
.Where(x => !x.IsInterface
&& x.GetInterface(typeof(IAsyncRepository<>).Name) != null);
foreach (var repositoryType in repositoryTypes)
{
// Adds a singleton service of BookRepository
services.AddSingleton(repositoryType);
}
像这样的东西会有用的
// Get all classes implementing IAsyncRepository
var repositoryTypes = assembly.GetTypes().Where(x => !x.IsInterface &&
x.GetInterface(typeof(IAsyncRepository<>).Name) != null);
foreach (var repositoryType in repositoryTypes)
{
var type = repositoryType.UnderlyingSystemType;
services.AddSingleton(type.GetInterface($"I{type.Name}"), type);
}
//获取所有实现IAsyncRespository的类
var repositoryTypes=assembly.GetTypes()。其中(x=>!x.IsInterface&&
x、 GetInterface(typeof(iasyncpositional.Name)!=null);
foreach(repositoryTypes中的var repositoryType)
{
变量类型=repositoryType.UnderlineingSystemType;
AddSingleton(type.GetInterface($“I{type.Name}”),类型;
}
我不确定是否有更好的方法来获取接口类型这可能适用于OP的特定情况,只要遵循命名约定(我指的是接口的iSeries设备
和实现的服务:),通常它可能会失败。您只需获取过滤类型的所有接口(使用GetInterfaces
)并注册每个接口和类型的每对接口。这将涵盖所有的接口和类对,并有一个更好的结果。感谢您的回复!成功了!嘿@KingKing你是说这样吗var interfacetype=repositoryType.GetInterfaces()。其中(r=>!r.Name.Contains(typeof(iasyncrespository.Name))代码>这样我就可以循环类的所有接口并将单例添加到服务中:services.AddSingleton(interfaceType,repositoryType)
你怎么想?@Gabriel会尝试注册iAsyncRespository
的服务,因此它会错过像iBookRespository
这样的接口,实际上你需要一个约定或规则来选择你想要的接口,就像在你的例子中一样,我知道iBookRespository
是需要注册的(不是iasyncrecepository
)。如果您没有特定的约定或规则来过滤接口(从GetInterfaces()
),那么您可以将所有内容注册到实现中,这没有什么害处(DI容器会消耗一点额外的内存).IMHO,定义一个属性ServiceInterfaceAttribute
,将其添加到IBookRepository
,扫描程序集以查找使用该属性实现接口的任何类型?这可能会简化动态配置。。。
// Get all classes implementing IAsyncRepository
var repositoryTypes = assembly.GetTypes().Where(x => !x.IsInterface &&
x.GetInterface(typeof(IAsyncRepository<>).Name) != null);
foreach (var repositoryType in repositoryTypes)
{
var type = repositoryType.UnderlyingSystemType;
services.AddSingleton(type.GetInterface($"I{type.Name}"), type);
}