【问题标题】:Replace a service in servicecollection used by webhost in .net core替换.net核心中webhost使用的servicecollection中的服务
【发布时间】:2017-01-11 18:21:33
【问题描述】:

好的,所以我在运行时将一个类实例添加到startup.cs 的服务集合中,如下所示:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<WidgetProvider, BlueWidgetProvider>();
    }

但是,在运行时,我希望应用程序能够将 BlueWidgetProvider 替换为 RedWidgetProvider。我该怎么做呢?我知道您可以在IServicesCollection 上使用Remove 方法,但是我如何将其公开给我的应用程序?我可以公开添加了WidgetProviderIServiceProvider,如下所示,但我不确定如何访问底层服务集合。

    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build();

        Current.Services = host.Services;  //Here

        host.Run(Current.AppCancellationSource.Token);
    }

【问题讨论】:

  • 你如何确定应用程序需要哪个 WidgetProvider ?
  • 可能只是用户输入,让用户无需重新启动整个应用程序即可更改 WidgetProvider。

标签: c# .net dependency-injection asp.net-core


【解决方案1】:

对我有用的一种方法是取消host.Run 方法并像这样再次递归调用Main

进行一些设置更改,告诉启动在配置服务时使用不同的小部件提供程序:

public void UseRedWidgetProvider() {
    database.UseRedWidgetProvider();
    Restart();
}

方法取消host.Run方法:

public void Restart() 
{
    Current.AppCancellationSource.Cancel();
}

包含取消令牌的静态类:

public static class Current 
{
    public static CancellationTokenSource AppCancellationSource = new CancellationTokenSource();
}

在调用取消令牌后递归启动Main

public static void Main(string[] args)
{
    var host = new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseIISIntegration()
        .UseStartup<Startup>()
        .Build();

    CoreCurrent.Protector = ActivatorUtilities.CreateInstance<DataProtect>(host.Services);

    Current.Services = host.Services;

    Current.SetDbConfigurationState();

    host.Run(Current.AppCancellationSource.Token);

    //reset token and call main again
    host.Dispose();
    Current.AppCancellationSource = new System.Threading.CancellationTokenSource();
    Main(args);
}

这对我来说似乎工作正常。一旦我调用取消令牌,应用程序似乎会很快重新启动,并且现在使用新的小部件提供程序。不完全确定这是否是一种好的做法,或者是否有任何组件可能会被搞砸。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    相关资源
    最近更新 更多