Logging in Asp.Net Core

The logging is not usable in ASP.NET Core projects because it can’t be added within the ConfigureServices method.

Example:
I add the endpoint configuration within the ConfigureServices method in order to add the endpoint instance to the DI container.

public void ConfigureServices(IServiceCollection services)
{
  var endpointConfiguration = new EndpointConfiguration("xy");
  // ...

  var logFactory = NServiceBus.Logging.LogManager.Use<MicrosoftLogFactory>();
  var endpointInstance = Endpoint.Start(endpointConfiguration).GetAwaiter().GetResult();
  services.AddSingleton<IMessageSession>(endpointInstance);
  services.AddSingleton(logFactory);
}

The logging is added within the Configure method

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
  var logFactory = app.ApplicationServices.GetRequiredService<MicrosoftLogFactory>();
  logFactory.UseMsFactory(factory);
  //..
  app.UseMvc();
}

Now I get following exception
Exception: Call MicrosoftLogFactory.UseMsFactory() prior to starting endpoint.

The problem ist, that I can’t get access to the ILoggerFactory in the ConfigureServices.

The only workaround at moment seems to be:

var logFactory = NServiceBus.Logging.LogManager.Use();

// Adds the message bus logging to the logger factory.
// this is a workaround for Not usable in ASP.NET Core projects · Issue #1 · NServiceBusExtensions/NServiceBus.MicrosoftLogging · GitHub
var serviceProvider = services.BuildServiceProvider();
logFactory.UseMsFactory(serviceProvider.GetRequiredService<Logging.ILoggerFactory>());

var endpointInstance = Endpoint.Start(endpointConfiguration).GetAwaiter().GetResult();

Hi Toni

Yeah, that is one of the downsides when you start the endpoint instance where the service collection is available. I did that as a workaround as well in the Service Fabric Webinar because I required access to the StatelessServiceContext, see service-fabric-webinar/NServiceBusServiceCollectionExtensions.cs at master · danielmarbach/service-fabric-webinar · GitHub

Another draw back is that the entry point ConfigureServices cannot be made asynchronous, that’s why the start of the endpoint has to be done with GetAwaiter().GetResult(). An alternative option if you don’t like the workaround you described is to register some provider or message session decorator that gets you access to the message session and asynchronously initializes the endpoint on the first call. This provider could then have a constructor dependency to ILoggerFactory. Obviously, this has then the drawback that any wrong configuration on endpoint start will only be seen when the first request comes in and not during the bootstrapping part.

Regards
Daniel