4

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

asked Apr 27, 2017 at 6:33

1 Answer 1

5

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>();
})
answered Apr 27, 2017 at 8:55
Sign up to request clarification or add additional context in comments.

5 Comments

Mhmm ok thank you... I already tried to use the 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...
@timothy3001, I guess it's impossible to register a service in 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
Ok thank you. I don't really need to register a service in 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 you
@timothy3001, I've added example of original Startup.Configure method extending indead of replacement. Maybe it will be helpful. Thanks for the interesting question.
Oh wow, thanks a lot :) This seems to me the "cleanest" solution.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.