Search code examples
c#asp.net-core.net-coreasp.net-core-mvcasp.net-core-2.2

Asp.net Core MVC - obtaining dependency during app shutdown


I'm developing a web app using ASP.net Core MVC 2.2, and in my Startup class I'm registering a dependency injection of type MyService, like so:

public void ConfigureServices(IServiceCollection services)
{
    //Inject dependency
    services.AddSingleton<MyService>();

    //...other stuff...
}

This works correctly. However, I need to retrieve the instance of MyService during application shutdown, in order to do some cleanup operations before the app terminates.

So I tried doing this - first I injected IServiceProvider in my startup class, so it is available:

public Startup(IConfiguration configuration, IServiceProvider serviceProvider)
{
    ServiceProvider = serviceProvider;
    Configuration = configuration;
}

and then, in the Configure method, I configured a hook to the ApplicationStopping event, to intercept shutdown and call the OnShutdown method:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime applicationLifetime)
{
    //Register app termination event hook
    applicationLifetime.ApplicationStopping.Register(OnShutdown);

    //...do stuff...
}

finally, in my OnShutdown method I try obtaining my dependency and using it:

private void OnShutdown()
{
    var myService = ServiceProvider.GetService<MyService>();
    myService.DoSomething(); //NullReference exception, myService is null!
}

However, as you can see from the comment in the code, this doesn't work: the returned dependency is always null. What am I doing wrong here?


Solution

  • I was able to make it work by explicitly passing your application services to your shutdown method like so.

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime applicationLifetime)
    {
        //Register app termination event hook
        applicationLifetime.ApplicationStopping.Register(() => OnShutdown(app.ApplicationServices));
    
         //...do stuff...
    }
    
    
    private void OnShutdown(IServiceProvider serviceProvider)
    {
            var myService = serviceProvider.GetService<MyService>();
             myService.DoSomething();
    }
    

    Bare in mind that this will work for singleton services - you may have to CreateScope() if you want to resolve scoped services.