C# .Net核心依赖项注入:获取servicetype(接口)的实现类型
是否可以获取servicetype的已注册实现的类型 例如: 在我的C# .Net核心依赖项注入:获取servicetype(接口)的实现类型,c#,.net-core,dependency-injection,C#,.net Core,Dependency Injection,是否可以获取servicetype的已注册实现的类型 例如: 在我的Startup.ConfigureServices中,我注册了这样的服务(没有什么特别的): public void配置服务(IServiceCollection服务) { //... services.AddTransient(); //... } IBaseRepository是服务类型,BaseRepository是具体实现 问题 是否有方法获取服务接口的注册类型(而不是实例)? 在我的示例中,我想请求IBaseRepo
Startup.ConfigureServices
中,我注册了这样的服务(没有什么特别的):
public void配置服务(IServiceCollection服务)
{
//...
services.AddTransient();
//...
}
IBaseRepository
是服务类型,BaseRepository
是具体实现
问题
是否有方法获取服务接口的注册类型(而不是实例)?
在我的示例中,我想请求IBaseRepository
并获取类型BaseRepository
于2021年2月10日13:13 UTC编辑:以下信息不是问题的一部分,具有误导性。
我的问题的更多背景信息
稍后,我需要这个服务的一个实例,并希望使用
,因为我需要在构造函数中传递值,该值只有在运行时才知道。
在这里,我需要为我想要获得新实例的类传递具体类型。
如果我可以将接口类型传递到我的方法中,确定为该接口注册了哪个类并创建一个新实例,那就太好了。对于您的场景,您实际上不需要使用ActivatorUtilities: 从about
GetRequiredService
查看此代码,因为我认为它将解决您的问题
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
using (var serviceScope = host.Services.CreateScope())
{
var services = serviceScope.ServiceProvider;
try
{
var myDependency = services.GetRequiredService<IMyDependency>();
myDependency.WriteMessage("Call services from main");
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred.");
}
}
host.Run();
}
publicstaticvoidmain(字符串[]args)
{
var host=CreateHostBuilder(args.Build();
使用(var serviceScope=host.Services.CreateScope())
{
var services=serviceScope.ServiceProvider;
尝试
{
var myDependency=services.GetRequiredService();
myDependency.WriteMessage(“主叫服务”);
}
捕获(例外情况除外)
{
var logger=services.GetRequiredService();
LogError(例如,“发生错误”);
}
}
host.Run();
}
为什么这是首选:
瞬态作用域服务,因此它应该是正常的。如果这是一个单例,那么由activator创建一个新的单例将是一个糟糕的做法,因为您将违反原始作者的意图,并产生未知的副作用(好的,它们可能是已知的,但您明白我的意思)
现在还不完全清楚你为什么需要这个,但是。。。
IServiceCollection
(不是内置的IServiceProvider
)只是对象的集合。用于配置DI的所有扩展方法本质上都是向集合添加一个或多个描述符
因为它实现了IList
(因此IEnumerable
),所以您可以对它执行LINQ操作以查找特定的描述符。ServiceDescriptor
上有四个值得注意的属性,它们描述服务及其实现
-必需;将从DI请求的服务类型
。通常但不总是一个接口类型
-可选;已注册的混凝土实现类型
类型
-可选;单例实例(静态类型实现实例
)对象
-可选;用作工厂方法的实现工厂
Func
Lifetime
描述了生存期(单例、作用域、瞬态)
如果要查找与特定服务类型关联的具体类型s,可以使用以下扩展方法:
公共静态IEnumerable GetImplementationTypes(此IServiceCollection服务)
where-TService:class
{
if(服务为空)
抛出新的ArgumentNullException(nameof(services));
回程服务
。其中(d=>d.ServiceType==typeof(TService)&&d.ImplementationType!=null)
.选择(d=>d.ImplementationType);
}
//或者
公共静态IEnumerable GetImplementationTypes(此IServiceCollection服务,类型serviceType)
{
if(服务为空)
抛出新的ArgumentNullException(nameof(services));
if(serviceType为null)
抛出新ArgumentNullException(nameof(serviceType));
回程服务
.Where(d=>d.ServiceType==ServiceType&&d.ImplementationType!=null)
.选择(d=>d.ImplementationType);
}
然后您可以使用:
IServiceCollection服务=。。。
var typeList=services.GetImplementationTypes().ToList();
请注意,这将返回一个
IEnumerable
,因为您可以对单个服务类型进行多个注册。它还将只返回那些已注册类型的,而不返回那些使用工厂或单实例的。嗨,Athanasios,谢谢你的回答。但是GetRequiredService
如何帮助将参数传递给服务的构造函数,而该构造函数未在DI容器中注册?您将传递参数并在类中使用GetRequiredService。或者是我误解了什么?对不起,我知道我的问题不清楚。毫无疑问,如何使用ActivatorUtilities.CreateInstance
。问题是如何获取为servicetype注册的IMementations的信息。这似乎是一个问题。根据背景,目前的问题也不完整,因此不清楚。阅读并编辑问题,以提供一个可用于重现问题的答案,从而获得更好的答案