C# 在运行时通过DI注册服务?
我正在使用ASP.NET Core,希望在运行时向IServiceProvider添加一个服务,以便通过DI在整个应用程序中使用它 例如,一个简单的示例是,用户转到设置控制器并将身份验证设置从“开”更改为“关”。在这种情况下,我希望替换在运行时注册的服务C# 在运行时通过DI注册服务?,c#,asp.net-core,asp.net-core-mvc,.net-core,C#,Asp.net Core,Asp.net Core Mvc,.net Core,我正在使用ASP.NET Core,希望在运行时向IServiceProvider添加一个服务,以便通过DI在整个应用程序中使用它 例如,一个简单的示例是,用户转到设置控制器并将身份验证设置从“开”更改为“关”。在这种情况下,我希望替换在运行时注册的服务 services.AddTransient<AuthenticationService>(); services.AddTransient<NoAuthService>(); services.AddTransient&
services.AddTransient<AuthenticationService>();
services.AddTransient<NoAuthService>();
services.AddTransient<IAuthenticationServiceFactory, AuthenticationServiceFactory>();
设置控制器中的Psuedo代码:
if(settings.Authentication == false)
{
services.Remove(ServiceDescriptor.Transient<IAuthenticationService, AuthenticationService>());
services.Add(ServiceDescriptor.Transient<IAuthenticationService, NoAuthService>());
}
else
{
services.Remove(ServiceDescriptor.Transient<IAuthenticationService, NoAuthService>
services.Add(ServiceDescriptor.Transient<IAuthenticationService, AuthenticationService>());
}
if(settings.Authentication==false)
{
Remove(servicescriptor.Transient());
Add(servicescriptor.Transient());
}
其他的
{
删除(servicescriptor.Transient)
Add(servicescriptor.Transient());
}
当我在Startup.cs中执行此操作时,此逻辑工作正常,因为IServiceCollection尚未内置到IServiceProvider中。但是,我希望在启动已执行后能够执行此操作。有人知道这是否可行吗?我将创建一个服务工厂,而不是在运行时注册/删除服务hich在运行时决定正确的服务
services.AddTransient<AuthenticationService>();
services.AddTransient<NoAuthService>();
services.AddTransient<IAuthenticationServiceFactory, AuthenticationServiceFactory>();
类中的用法:
public class SomeClass
{
public SomeClass(IAuthenticationServiceFactory _authenticationServiceFactory)
{
var authenticationService = _authenticationServiceFactory.GetAuthenticationService();
}
}
@Dawid你说这是什么权威的“正确的方法”?你的意思是“我也会这样做”?为什么?为什么这是一个好答案?因为从设计模式的角度来看,注册工厂隐藏一些细节更好(在这种情况下,获得一些配置/设置)并且只提供正确的实现。谢谢,但我认为这对我不起作用。为了说明这个概念,我将我的示例非常简单,但这不是我的实际问题。我有一个模块化系统,可以“安装”插件在运行时,这些插件有需要添加到ServiceCollection的服务。我的问题是,我没有找到一种在运行时添加这些服务的令人满意的方法。感谢您花时间响应!@CodeCaster:
ServiceCollection
也不应该在引导后更改。该提供程序是在en ASP.NET核心调用services.buildServiceProvider()
(在ConfigureServices
之后和Configure
调用之前的某个地方),对IServiceCollection
的更改无关紧要,再次调用.buildServiceProvider()
只是创建了一个新的提供者,旧的提供者仍然在singleton服务中被引用,这在change@A.Fry:无论是否在运行时,您都需要重新启动应用程序才能执行此操作。或者使用允许在运行时更改依赖项的容器。正如您在此处看到的,ServiceProvider是内部的,没有公共的更改其ServiceTable
集合的方法