我正在使用VS 2017和.NET Core。 使用依赖注入,我想在运行时动态注册我的服务。我的目标是编写我的服务实例,在不同的程序集中实现服务接口。然后将servicename /程序集名称添加到某种配置文件(或db表)中。
我的注册码会执行以下操作:
var ServiceTypeName = LoadServiceAssembly(AssemblyName);
var serviceProvider = new ServiceCollection()
.AddTransient<IDILogger, "ConsoleDILogger">() // <--- Goal
.BuildServiceProvider();
var logger = serviceProvider.GetService(IDILogger);
显然,AddTransient行不起作用,因为这样的方法不存在。然而,它确实描绘了这个想法。我想通过字符串名称注册类型,以便每次添加新服务类型时都不需要重新编译加载器应用程序。
我似乎无法找到如何做到这一点。欢迎大家提出意见。
TIA
答案 0 :(得分:7)
您可以从设置中读取已配置的类型,通过反射加载所需的类型并在服务集合中注册它:
header {min-height: 100px;}
如果添加或重新配置新的记录器,这种动态方法将不需要任何重新编译。
答案 1 :(得分:3)
这显然不可能,但是,我在项目中使用了与此类似的东西,以避免必须将每个新类型添加到容器中:
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);
}
对于您的具体情况,您甚至可以缩短它:
var type = assembly.ExportedTypes.First(x => x.Name == runtimeName);
services.AddScoped(typeof(IDILogger), type);
答案 2 :(得分:0)
您可以使用工厂来实现这一目标。
public class NoCacheAttribute : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.SetNoStore();
base.OnResultExecuting(filterContext);
}
}