Master ASP.NET Core 2.1 : Instructor-led online course conducted by Bipin Joshi. Next batch starting from 30 December 2018. Limited seats. More details are available here.

Utilize ASP.NET Core Application Lifetime Events

At times you need to know when your ASP.NET Core web application is being started and shutdown. One of the lesser known features of ASP.NET Core is the IApplicationLifetime interface that allows you to wire some logic when such application lifetime events occur. This article briefly discusses the IApplicationLifetime interface and its functionality.

 IApplicationLifetime interface

The IApplicationLifetime interface comes from Microsoft.AspNetCore.Hosting. This interface exposes certain useful members :

  • ApplicationStarted : This property can be used to hook a callback that is executed when an application host is started.
  • ApplicationStopping : This property can be used to hook a callback that is executed when an application host is about to stop. Some requests might be pending at this stage.
  • ApplicationStopped : This property can be used to hook a callback that is executed when an application has been stopped. All the requests are complete at this stage.
  • StopApplication() : This method allows you to shutdown an application programmatically.

You might use these callbacks to flush out logs or send some notifications. These three properties are actually CancellationTokens and allow us to register Action callbacks. Remember that StopApplication() should be used with caution after evaluating the consequences as it shuts down the current application.

The IApplicationLifetime is registered with the DI container. You can inject it in Configure() or some controller.

Ok. Let's create a simple ASP.NET Core MVC application that illustrates the usage of these properties and method. As an example we will log messages in a text file to confirm that a particular callback has been called.

Handling ApplicationStarted, ApplicationStopping, and ApplicationStopped

Create a new ASP.NET Core MVC application and open the Startup class. Then add the following code to the class, ConfigureServices(), and Configure() method:

private IHostingEnvironment env;

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
}
public void Configure(IApplicationBuilder app, 
IHostingEnvironment env)
{
    this.env = env;

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseMvcWithDefaultRoute();
}

The Configure() method receives an object of IHostingEnvironment. We store it in a private variable for later use. We need this object because we want to compute the log file path in the callback methods.

Now, modify the Configure() method signature to include IApplicationLifetime as shown below :

 public void Configure(IApplicationBuilder app, 
IHostingEnvironment env,
IApplicationLifetime lifetime)
{
  ...
  ...
}

Once you inject IApplicationLifetime into Configure() method you can wire the callbacks discussed earlier. The following code shows how:

public void Configure(IApplicationBuilder app, 
IHostingEnvironment env,
IApplicationLifetime lifetime)
{
    this.env = env;
    ...
    ...
    lifetime.ApplicationStarted.Register(OnAppStarted);

    lifetime.ApplicationStopping.Register(OnAppStopping);

    lifetime.ApplicationStopped.Register(OnAppStopped);

    app.UseMvcWithDefaultRoute();
}

The three properties namely ApplicationStarted, ApplicationStopping, and ApplicationStopped allow you to register callbacks. This is done using the Register() method. The three callbacks - OnAppStarted(), OnAppStopping(), and OnAppStopped() are shown below :

public void OnAppStarted()
{
    string path = $"{env.WebRootPath}/AppLog.txt";
    string contents = $"App started at {DateTime.Now}";
    File.AppendAllText(path, contents);
}


public void OnAppStopping()
{
    string path = $"{env.WebRootPath}/AppLog.txt";
    string contents = $"App stopping at {DateTime.Now}";
    File.AppendAllText(path, contents);
}


public void OnAppStopped()
{
    string path = $"{env.WebRootPath}/AppLog.txt";
    string contents = $"App stopped at {DateTime.Now}";
    File.AppendAllText(path,contents);
}

The callback method shown above simply log messages with timestamp to a text file named AppLog.txt.

To test the application, run it and then after some time close it using the system tray (IISExpress) or by pressing Ctrl + C in the console window (Kestrel).

This will trigger the graceful shutdown of the application and the events will be raised accordingly. The following figure shows the log messages after a sample run of the application :

Stopping an application programmatically

In the preceding application run you initiated the application shut down manually from system tray or console window. You can also stop an application using StopApplication() method of IApplicationLifetime.

Consider the following view that allows you to do that with a click of a button :

The view outputs a timestamp stored in IMemoryCahche. We do this just to confirm that the application has been stopped and IMemoryCache is emptied.

To modify the application open the Startup class and add  this line to ConfigureServices().

services.AddMemoryCache();

Then open the HomeController and inject IApplicationLifetime and IMemoryCache into the constructor :

private IApplicationLifetime lifetime = null;
private IMemoryCache cache = null;

public HomeController(IMemoryCache cache,
IApplicationLifetime lifetime)
{
    this.cache = cache;
    this.lifetime = lifetime;
}

Then write the Index() action as follows :

public IActionResult Index()
{
    if (cache.Get("timestamp") == null)
    {
        cache.Set<string>("timestamp", 
DateTime.Now.ToString());
    }
    ViewBag.TimeStamp = cache.Get<string>("timestamp");
    return View();
}

The Index() action simply checks whether an entry named timestamp exists in the IMemoryCache or not. If it doesn't exist, a new entry is added  otherwise the existing entry value is assigned to the ViewBag.Message.

Clicking the Stop Application button calls the Stop() action of HomeController. The Stop() action is shown below :

[HttpPost]
public IActionResult Stop()
{
    lifetime.StopApplication();
    return new ObjectResult
("Application stopped successfully!");
}

The Stop() action calls StopApplication() method of IApplicationLifetime. This causes the application shutdown. The action also returns a message to the browser accordingly.

If you run the application and click on the Stop Application button you will see the log entries in the AppLog.txt as before and the browser will show :

If you hit the application URL by opening a new tab, the application will be started again and you will get a new entry in the IMemoryCache (since the cache got emptied with the app shutdown).

That's it for now! Keep coding!!


Bipin Joshi is a software consultant, trainer, author, yoga mentor, and spiritual guide having 23+ years of experience in software development, consulting, and training. He conducts instructor-led online training courses in ASP.NET Core, ASP.NET MVC, and Design Patterns for individuals and small groups. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced the Yoga way of life he also teaches Ajapa Yoga to interested individuals. To know more about him click here.

Get connected : Twitter  Facebook  Google+  LinkedIn

Posted On : 19 November 2018


Tags : ASP.NET ASP.NET Core MVC C# Visual Studio


Subscribe to our newsletter

Get monthly email updates about new articles, tutorials, code samples, and how-tos getting added to our knowledge base.