I'm trying to implement a new extension method for the IWebHostBuilder
that executes some code, like registering somewhere.
The important part is, that it also unregisters when the application is shutting down.
I added some code which shows what I want to do. The problem here is, that the instance of IApplicationLifetime
is not available yet. This new extension method was added last in the pipeline of building the WebHost.
public static IWebHostBuilder UseHttpGatewayappRegistration(this IWebHostBuilder webHostBuilder)
{
webHostBuilder.ConfigureServices(services =>
{
var sp = services.BuildServiceProvider();
// This instance is not available
IApplicationLifetime applicationLifetime = sp.GetService<IApplicationLifetime>();
// These instances are ok
AppSettings appSettings = sp.GetService<AppSettings>();
ILoggerFactory loggerFactory = sp.GetService<ILoggerFactory>();
var registration = new Registration(loggerFactory.CreateLogger<Registration>());
applicationLifetime.ApplicationStopping.Register(() =>
{
registration.Unregister();
});
});
return webHostBuilder;
}
Why is the IApplicationLifetime
instance null, even though I added this extension method last in the pipeline of building the WebHost pipeline? It would be great, if someone would provide me with some information about the execution order of all "ConfigureServices" methods and how or if it is at all possible to use IApplicationLifetime
in a ConfigureServices
method.
I know I could do this all without the WebHostBuilder
, but it seems logical to me to do it there and I also think there has to be a way.
Unfortunately I couldn't find much information online...
Thank you.
EDIT: I found a way to use DI in ConfigureServices
methods. I edited the question accordingly. This helped me: How to Resolve Instance Inside ConfigureServices in ASP.NET Core
1 Answer 1
You can't get access to IApplicationLifetime
instance from ConfigureServices
method. It's by design. Check the "Services Available in Startup" section here:
Application Startup in ASP.NET Core.
Resolve IApplicationLifetime
in the IWebHostBuilder.Configure
method (it replaces the Startup.Configure
method if it is used later in IWebHostBuilder
configuration pipeline):
public static IWebHostBuilder Foo(this IWebHostBuilder webHostBuilder)
{
webHostBuilder.Configure(x =>
{
var service = x.ApplicationServices.GetService<IApplicationLifetime>();
});
return webHostBuilder;
}
It's also possible to extend the original Startup.Configure
method instead of replace (a lot of Reflection logic should be added to make this solution reliable):
.Configure(app =>
{
var env = app.ApplicationServices.GetService<IHostingEnvironment>();
dynamic startup = Activator.CreateInstance(typeof(TStartup), env);
//Carefully resolve all input parameters.
//Make sure all required services are registered in DI.
startup.Configure(app, env);
var lifetime = app.ApplicationServices.GetService<IApplicationLifetime>();
})
5 Comments
Configure
method. The problem is, I also use a Startup
class in parallel, so when I call the Configure
method in my extension method, the Configure
method in the Startup
class isn't called anymore...Configure
method. So, even if we create a Startup
instance manually and call Startup.ConfigureServices
from Configure
it won't be succeded. Probably it's better to re-design your extention method to a IApplicationBuilder
extention like this: stackoverflow.com/a/43610530/5112433 Configure
method but rather use the IApplicationLifetime
in a ConfigureServices
method to have a shutdown hook. My problem with putting it into the Startup
is, that it doesn't belong there in my opinion. It has nothing to do with the setup of HTTP pipeline. But since there's no alternative for now, I'll go ahead and do that. Thank youStartup.Configure
method extending indead of replacement. Maybe it will be helpful. Thanks for the interesting question.