ASP.NET Core – custom ILogger<T> and Nlog callsite layout renderer issue

1. Introduction

In my current project, we use Microsoft.Extensions.Logging.ILogger<T> default implementation as our logging mechanism. This basically comes with the ASP.NET Core 2.0 package and it was working fine so far. However recently we decided to switch the default implementation with a custom one, due to the fact that we wanted to have some additional logic applied for all of the logging providers.

2. Implementation

The custom implementation itself is very similar to the original one, we came up with something like that

and we replaced the default logger with this code

As you can see we basically wanted to add information from custom exceptions to the message. Due to the fact that this is added in here, we don’t have to modify all of our existing logging providers.

3. NLog call site renderer issue

Once we run the application all of the providers were working fine and were producing expected output apart from NLog provider. Originally NLog provider for the following code

was producing this output

However, after introducing new implementation of ILogger<T>, it started appending wrong caller member name

After some digging, it turned out that the issue lies in the (indirect)configuration of NLog’s callsite layout renderer. Long story short, when you add NLog provider to your logger providers, under the hood it adds Microsoft.Extensions.Logging.Abstractions assembly(among others) to something called hidden assembly collection. Once the NLog tries to figure out what is the caller member name, it crawls the stack trace to find a method name. If the method in current frame comes from a hidden assembly, logger skips it and continues iteration. As we changed the Logger<T> to our custom one, it is no longer part of Microsoft.Extensions.Logging.Abstractions assembly, so the NLog reports Log method from our custom logger as a caller member name.

4. The fix

In order to restore previous behavior you have to add custom logger assembly to the hidden assembly collection. You can do it via

Of course, if the logger is located in the same assembly as rest of your code, this might not be the perfect solution – as this will impact the way the callsite is rendered for other parts of your code in this assembly. In that case, you might consider moving the logging piece to separate assembly or resign from using callsite layout renderer at all. We decided to replace it with logger layout renderer as callsite layout renderer, either way, wouldn’t be used in production environments.

Source code for this post can be found here

ASP.NET Core – custom ILogger<T> and Nlog callsite layout renderer issue

ASP.NET Core – make sure IOptions<T> is initialized

1. Introduction

As most people know IOptions<T> is a convenient way of handling configuration options in your application. Even though I’ve been using it for quite some time, last week I was unpleasantly surprised by a production bug caused by wrong usage of this mechanism.

2. Problem

Let’s say we have a simple controller which depends on two instances of IOptions<T>

Then we add only IOptions in Startup class – IOptions<PaymentOptoins>

Now, when we run the app and hit one of the endpoints in ValuesController I was expecting to get an exception, as I didn’t register IOptions<NotificationOptions>. Surprisingly for me, the application was running normally and IOptions<NotificationOptions> was created with the new instance of NotificationOptions class(with all the properties defaulted).

In order to find out why it behaves like that we have to take a look how services responsible for handling IOptions<T> are registered in the container.

As you can see AddOptions method registers open generics for (among others) IOptions<> which means that you don’t have to register specific types of IOptions<T>, however, you are responsible for its configuration with

I was always convinced that services.Configure registers and configure IOptions<T> but apparently, I was wrong.

3. Ensuring initialization

As these kind of errors are rather difficult to catch(at least in case of our application) I wanted to minimize the risk of doing the same bug again. The idea was to make sure that at least one IConfigureOptions<T> or IPostConfigureOptions<T> service is registered in the container (as these are the services which are responsible for setting the values of T class). My first approach was to replace default OptionsFactory<T> with a custom one

This method works fine (although probably needs smarter TOptions filter)

however I got to conclusion that there is no point to do validation in a runtime, and the integration test might be a better choice. I came up with following code (I am assuming that all configuration options are stored in the same assembly, as this is convention in my project)

Running the test shows that NotificationOptions was not configured

Source code for this post can be found here

ASP.NET Core – make sure IOptions<T> is initialized

ASP.NET Core – passing command-line arguments to Startup class

1. Introduction

I usually pass configuration to my web API via JSON files, but recently I needed to pass them also via command-line arguments. As the solution for ASP.NET Core 2.x is quite different than for ASP.NET Core 1.x I decided to describe both methods in here.

2. ASP.NET Core 2.x

For the newest version of ASP.NET Core, the solution is pretty straightforward as IConfiguration is injected by default to the Startup class. All we have to do is to add CommandLineConfigurationSource to IConfigurationBuilder when configuring IWebHost. CommandLineConfigurationSource is part of the Microsoft.Extensions.Configuration.CommandLine package and can be easily used by AddCommandLine extension method

Now we can access our command-line arguments just like any other configuration

3. ASP.NET Core 1.x

The solution for ASP.NET Core 1.x requires a bit more work but it is possible to achieve the same result. We still will be using CommandLineConfigurationSource from Microsoft.Extensions.Configuration.CommandLine package, however this time we have to manually create IConfiguration object and register it in the container before the Startup class is created. This is possible because the WebHostBuilder exposes ConfigureServices method.

Having our service registered now we can easily access IConfiguration object in our application


Source code for this post can be found here

ASP.NET Core – passing command-line arguments to Startup class

ASP.NET Core – retrieving swagger specification without hosting API

1. Introduction

I am currently exploring possible ways of removing a repetitive work when it comes to creating integration tests for our API. The one thing which usually takes some time when testing a new endpoint is a process of creating response and request classes (as we don’t share the models between API project and integration test project). That is why I would like to have some kind of a tool (AutoRest or NSwag) which would do it for us (possibly, in a prebuild step). As those tools generate API clients based on swagger specification and I wanted this process to be as fast as possible I decided to figure out the way how to retrieve swagger specs without hosting the API.

2. Implementation

After taking a look at Swashbuckle.AspNetCore.Swagger source code it turned out that Swashbuckle.AspNetCore.Swagger.ISwaggerProvider is responsible for creating a SwaggerDocument class. JSON representation of that class is a swagger specification. Having all of that in mind I wrote following piece of code.

The Program class is an entry point of the API. The only one difference compared to default ASP.NET Core template is the fact that I made the BuildWebHost method public. Thanks to that we can build the host (but without running) and get our hands on the DI container of our application. From that point the rest is easy, I retrieve the ISwaggerProvider from the container so I can get the swagger document for given id.

In order to make sure that the SchemaRetriever works as expected I wrote simple integration test which makes sure that swagger specs from hosted API is the same as the one retrieved without hosting.


Source code for this post can be found here

ASP.NET Core – retrieving swagger specification without hosting API

ASP.NET Core MemoryCache – GetOrCreate calls factory method multiple times

Recently I’ve been trying to locate a performance issue in our application. Stress tests have shown an excessive usage of memory combined with too many external server requests. As usual in such cases, I’ve run the profiler and after a bit of searching, I’ve noticed that issue is connected with our caching mechanism. The problematic part was a factory delegate (responsible for populating cache, if the cache for given key is empty) which was called multiple times when concurrent requests were sent. That was a bit surprising to me as we basically were using a very naïve wrapper over ASP.NET Core MemoryCache.

However simple test proved that this was an actual issue


After doing a bit of a digging it turned out that this was by-design behavior, which is documented in the very end of official documentation . However, as this behavior wasn’t the one we were expecting, we decided to reduce amount of factory calls by applying custom logic. We had couple of ideas when it comes to implementation, including:

  • Exclusive lock over factory method
  • Lock per key
  • Lock per type

After discussion we decided to go with third option, mainly because we didn’t want to over-complicate the design, plus we wanted to allow concurrent factory method calls for different types of objects. Once CacheService was updated with following code

we stoped experiencing excessive memory usage.

Source code for this post can be found here

ASP.NET Core MemoryCache – GetOrCreate calls factory method multiple times