C#依赖注入运行时(动态)注册

xgp*_*xgp 6 c# dependency-injection .net-core

我正在使用VS 2017和.NET Core.使用依赖注入,我想在运行时动态注册我的服务.我的目标是编写我的服务实例,在不同的程序集中实现服务接口.然后将servicename /程序集名称添加到某种配置文件(或db表)中.

我的注册码会做这样的事情:

var ServiceTypeName = LoadServiceAssembly(AssemblyName); 

var serviceProvider = new ServiceCollection()
 .AddTransient<IDILogger, "ConsoleDILogger">()  // <--- Goal
 .BuildServiceProvider();

var logger = serviceProvider.GetService(IDILogger);
Run Code Online (Sandbox Code Playgroud)

显然,AddTransient行不起作用,因为这样的方法不存在.然而,它确实描绘了这个想法.我想通过字符串名称注册类型,以便每次添加新服务类型时都不需要重新编译加载器应用程序.

我似乎无法找到如何做到这一点.欢迎大家提出意见.

TIA

SO *_*ood 9

这显然是不可能的,但是,我在一个项目中使用了类似的东西来避免将每个新类型添加到容器中:

var assembly = typeof(YourClass).Assembly; // I actually use Assembly.LoadFile with well-known names 
var types = assembly.ExportedTypes
   // filter types that are unrelated
   .Where(x => x.IsClass && x.IsPublic);

foreach (var type in types)
{
    // assume that we want to inject any class that implements an interface
    // whose name is the type's name prefixed with I
    services.AddScoped(type.GetInterface($"I{type.Name}"), type);
}
Run Code Online (Sandbox Code Playgroud)

对于您的具体情况,您甚至可以将其缩短:

var type = assembly.ExportedTypes.First(x => x.Name == runtimeName);
services.AddScoped(typeof(IDILogger), type);
Run Code Online (Sandbox Code Playgroud)


Cod*_*ler 8

您可以从设置中读取已配置的类型,通过反射加载所需的类型并在服务集合中注册它:

//  Read from config
var assemblyPath = "...";
var typeName = "...";

var assembly = Assembly.LoadFrom(assemblyPath);
var loggerType = assembly.GetType(typeName);

var serviceProvider = new ServiceCollection()
    .AddTransient(typeof(IDILogger), loggerType)
    .BuildServiceProvider();

var logger = serviceProvider.GetService<IDILogger>();
Run Code Online (Sandbox Code Playgroud)

如果添加或重新配置新记录器,则此类动态方法不需要任何重新编译.