Registering Multiple Implementations of an Interface with Service Collection in ASP.NET Core
Full source code here.
_This is a simplistic approach to the problem and assumes that the dependencies created by the factory do not in turn have their own dependencies. This deficiency could be mediated by passing those dependencies into the factory. Having said that it will be of use in some scenarios. I will publish a post in the future providing a better solution.
In a later post I will show how to use Autofac to do this properly. _
The out-of-the-box dependency injection container provided by Microsoft as part of ASP.NET Core is fine for most scenarios, only in a few complicated cases have I needed to switch to Castle or AutoFac.
But there is one somewhat common case where the
ServiceCollection feels a little deficient. There are times when you might have more than one implementation of an interface and you would like to choose between them at runtime.
There is no obvious way to do this.
You could try something like -
But when you request an implementation of
IValuesService in the constructor of a controller, the service collection will return the last registered service, in this case it will always return the
But what if you wanted the
PositiveValuesService in some controllers and the
NegativeValuesService in other controllers. What if you needed to choose the service implementation based on the address of the request that the controller is handling.
Something like this -
localhost:5000/NegativeValues – should use the
localhost:5000/PositiveValues – should use the
Using a Factory
Instead of registering two implementations of the
IValuesService, I’m going to create a
ValuesServiceFactory that returns the right service based on the path of the request.
ValuesServiceFactory has a method that looks like this -
_httpContextAccessor is what lets me access the
Request from inside the factory.
A few weeks ago I wrote about post about accessing the
HttpRequest from inside the constructor of a controller or from the constructor of a service the controller depends on.
That post had a contrived example, but this post has a more practical use of the technique.
The constructor of the
ValuesServiceFactory needs to take an
Startup.cs, remove the code registering the two services and replace with a line to register the factory and the
The controllers now take the implementation of
IValuesServiceFactory and request the an
IValuesService from the factory.
Do the same in the other controller -
That’s it, now you can choose between implementation of an interface. As I was working on this post I came across a post by Steve Gordon on this topic, he solves the same problem in a different way.
Full source code here.
- Registering Multiple Implementations of an Interface in ASP.NET Core with Autofac
- Accessing the HttpContext from the Constructor of a Controller or a Dependency
- Polly and Blazor, Part 3 - Dependency Injection
- Passing Configuration Options Into Middleware, Services and Controllers in ASP.NET Core 3.1
- Simmy Chaos Engine for .NET – Part 4, Doing Some Real Damage, Dropping a Table