Ok, so I have a class instance being added to the services collection in startup.cs
during runtime like so:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<WidgetProvider, BlueWidgetProvider>();
}
However, while running I want the application to be able to replace the BlueWidgetProvider
with a RedWidgetProvider
. How would I go about doing this? I know you can use the Remove
method on an IServicesCollection
, but how would I expose this to my application? I can expose the IServiceProvider
that has the WidgetProvider
added like below, but I'm not sure how I'd go about accessing the underlying services collection.
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);
}
Well one method that's working for me is to cancel the host.Run
method and recursively call Main
again like this:
Make some setting change that tells startup to use a different widget provider when configuring services:
public void UseRedWidgetProvider() {
database.UseRedWidgetProvider();
Restart();
}
Method to cancel host.Run
method:
public void Restart()
{
Current.AppCancellationSource.Cancel();
}
Static class to contain cancellation token:
public static class Current
{
public static CancellationTokenSource AppCancellationSource = new CancellationTokenSource();
}
Recursively start Main
after cancellation token is invoked:
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);
}
This appears to be working ok for me. Once I invoke the cancellation token the app appears to restart fairly quickly and the new widget provider is now used. Not entirely sure if this is a good practice or if there are any components that might be messed up.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.