6

When I power my APIs with Swagger, I follow one of those guids and I always put the MVC injections before Swagger injections like this.

services.AddMvc();
services.AddSwaggerGen(_ => { ... });

app.UseMvc();
app.UseSwagger();
app.UseSwaggerUI(c => { ... });

A friend of mine asked why I apply that order and not handle the Swagger related lines first, before MVC. I discovered that I couldn't explain that to him nor motivate it (other than a very embarrassed well... that's the way it is...). That tells me that I should dig a bit into that matter.

Short googling revealed nothing of relevance as far I've noticed, so I'm asking here.

Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
  • The docs should be of some help https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-2.2 – Nkosi Dec 25 '18 at 20:28

1 Answers1

8

In this particular case, Add* is not affected by the order they are added to the service collection.

However, depending on the implementation of the particular Add* extension, the order may affect configuration. For example, if internally it uses the TryAdd* extension, then only the first call registers. Subsequent calls wont add as a registration would already exist.

The general AddScoped/AddSingleton/AddTransient calls recognizes the last call for a type as it overrides the previous registration calls for that type. When registering multiple implementations for a type, for resolving via IEnumerable<T> then the implementations in the collection will be in the order they were registered.

Reference Dependency injection in ASP.NET Core

For the Use* middleware the order they are added to the pipeline is important as they are invoked in the same order.

Order

The order that middleware components are added in the Startup.Configure method defines the order in which the middleware components are invoked on requests and the reverse order for the response. The order is critical for security, performance, and functionality.

Reference ASP.NET Core Middleware

In my experience, depending on their designed purpose, some 3rd party integrations (including swagger) that need access to the pipeline suggest adding their extensions after AddMvc to try and avoid route conflicts.

Most security (Authentication/Authorization) and logging middleware are usually suggested to be added early in the pipeline, so they tend to come before AddMvc.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • 1
    _Short story is Add* is not affected by the order they are added to the service collection_ maybe be true for the above case, but not in general and depends on the implementation of the `Add*` method. If you have two `Add*` extension methods with `TryAdd*`calls within `Add*` method, then order do matter, since only the first one will add its registration, the second wouldn't add if an registraiton exists. – Tseng Dec 26 '18 at 01:42
  • 1
    @Tseng Good point. I'll see how I can reword my initial sentence to incorporate that. – Nkosi Dec 26 '18 at 01:44
  • Also the later `AddScoped/AddSingleton/AddTransient` calls overrides the resolving of an previously registered object (when a single instance is resolved, `IEnumerable` will return all registrations in the order they were registered) iirc and a [ReplaceAll](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.extensions.servicecollectiondescriptorextensions.removeall?view=aspnetcore-2.1) could be called within a `.AddXxx` extension method xD – Tseng Dec 26 '18 at 01:50