NSubstitute.Analyzers 1.0.0 released

A while ago I’ve announced a release of the first beta package of NSubstitute.Analyzers. Now, 4 months later I am happy to say that the first stable version is available for download. As usual, analyzers comes with two flavors:

Both of them come together with 19 diagnostics, which will warn you against common misusages of NSubstitue API. Feel free to grab them from NuGet and try them in your project. In case of any issues don’t hestitate to report a bug via GitHub issue tracker.

NSubstitute.Analyzers 1.0.0 released

Announcing NSubstitute.Analyzers (beta)

1. Introduction

I am glad to announce that yesterday, together with NSubstitute team we released first beta version of Roslyn analyzers for NSubstitute – NSubstitute.Analyzers. The analyzers come in two flavors: NSubstitute.Analyzers.CSharp and NSubstitute.Analyzers.VisualBasic. Feel free to grab them from NuGet and try them in your project.

2. Diagnostics

As for today analyzers can detect two most common misusages of NSubstitute:

  • non-virtual call setup
  • Received used without following method call

Feels free to suggest additional diagnostic you would like to have in the package.

Announcing NSubstitute.Analyzers (beta)

 ASP.NET Web API 2 – missing swagger query parameters

Last week I’ve encountered an interesting bug in swagger documentation of our API. For some reason couple of Get operations were missing some of the query parameters. The issue itself was only visible in a couple of controllers, simplified version of one of them is shown below

As you can see the controller has a Get method which takes as an argument following class

If you run swagger for Get operation you will see that only two parameters are listed in a parameter list

After some digging I found the actual problem were basically [DataMember] and [DataContract] attributes randomly scattered in the models used in Get methods arguments. Even though these attributes are not used for model binding from the query string, swagger takes them into account either way. It happens basically because swagger under the hood uses JsonObjectContract (even for [FromUri] request classes) and by default it respects [DataContract] attribute – more info can be found here. Removing redundant [DataContract] and [DataMember] attributes from respective models solved the issue.

PS. This particular corner case is not an issue for ASP.NET Core swagger implementation.

 ASP.NET Web API 2 – missing swagger query parameters

Solution-wide project properties with Directory.Build.props

1. Problem

When you work with a solution which contains multiple projects, you usually have some kind of convention which is applied to all of the projects. For instance, in my case, I always make sure that Stylecop.Analyzers package is installed and properly configured in every project. In this particular case, this boils down to adding these lines into the csproj file

Unfortunately, you have to add these lines to every project in a solution in order to make the Stylecop.Analyzers work for given project. This might be fine if you create all of them up front, but in real life scenario sooner or later you will add a new project to the solution. In that case, you might forget about adding those magic lines, so you will end up with inconsistent coding style in your repository. An additional problem with this approach is a code duplication so in case you rename StyleCop.json file you will have to make sure you update it everywhere. A partial solution for that problem is a manual import of custom made .props file, however, this approach is not perfect as well. The import part is not automatic, that is why you still have to remember about adding import directive to all of your projects.

2. Solution

Fortunately starting form MSBuild 15 you can bypass the limitations mentioned above thanks to automatic imports of properties from Directory.Build.props file. All you have to do is to create a beforementioned file in the root folder of your solution and you are good to go. The properties defined in the Directory.Build.props file will be automatically propagated to all of the child projects. In my case, this file looks as follows

The sample application which leverages this feature can be found here

Solution-wide project properties with Directory.Build.props

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