Cyberboss.AspNetCore.AsyncInitializer
Asynchronous initialization for ASP.NET Core hosts
ApplicationBuilderExtensions.cs
Go to the documentation of this file.
1 using Microsoft.AspNetCore.Builder;
2 using Microsoft.AspNetCore.Hosting;
3 using Microsoft.Extensions.DependencyInjection;
4 using System;
5 using System.Net;
6 using System.Threading;
7 using System.Threading.Tasks;
8 
9 namespace Cyberboss.AspNetCore.AsyncInitializer
10 {
14  public static class ApplicationBuilderExtensions
15  {
24  public static void UseAsyncInitialization<TDependency>(this IApplicationBuilder applicationBuilder, Func<TDependency, CancellationToken, Task> asyncInitializer)
25  {
26  if (applicationBuilder == null)
27  throw new ArgumentNullException(nameof(applicationBuilder));
28  if (asyncInitializer == null)
29  throw new ArgumentNullException(nameof(asyncInitializer));
30 
31  applicationBuilder.UseAsyncInitialization((cancellationToken) => asyncInitializer(applicationBuilder.ApplicationServices.GetRequiredService<TDependency>(), cancellationToken));
32  }
33 
40  public static void UseAsyncInitialization(this IApplicationBuilder applicationBuilder, Func<CancellationToken, Task> asyncInitializer)
41  {
42  if (applicationBuilder == null)
43  throw new ArgumentNullException(nameof(applicationBuilder));
44  if (asyncInitializer == null)
45  throw new ArgumentNullException(nameof(asyncInitializer));
46 
47  var applicationLifetime = applicationBuilder.ApplicationServices.GetRequiredService<IApplicationLifetime>();
48  Task initializationTask = null;
49  var tcs = new TaskCompletionSource<object>();
50 
51  async Task AsyncProcess()
52  {
53  using (applicationBuilder.ApplicationServices.CreateScope())
54  await asyncInitializer(applicationLifetime.ApplicationStopping).ConfigureAwait(false);
55  }
56 
57  applicationLifetime.ApplicationStarted.Register(() =>
58  {
59  initializationTask = AsyncProcess();
60  tcs.SetResult(null);
61  });
62 
63  var applicationStopping = applicationLifetime.ApplicationStopping;
64  applicationBuilder.Use(async (context, next) =>
65  {
66  await tcs.Task.ConfigureAwait(false);
67  if(!initializationTask.IsCompleted || applicationStopping.IsCancellationRequested)
68  {
69  context.Response.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
70  return;
71  }
72  await initializationTask.ConfigureAwait(false);
73  await next().ConfigureAwait(false);
74  });
75  }
76  }
77 }
static void UseAsyncInitialization(this IApplicationBuilder applicationBuilder, Func< CancellationToken, Task > asyncInitializer)
Runs a Task once applicationBuilder has started
Asynchronous initialization extensions for IApplicationBuilder