ASP.NET Core Web API — Avoid Dependency Injection Duplication
Leveraging Base Controllers and Dependency Injection to stick to the DRY Principle
Scenario
In most medium to large web API’s, most controller classes tend to use common services such as ILoggers.
Even though ASP.NET Core makes most services easy to access via dependency injection, sometimes initializing controller classes can get repetitive, and thus making it difficult to stick to the DRY principle.
Take the below snippet of code for instance. Out of the five services being injected, probably four of them will be re-used in other controllers. This means each of these controllers will have to be initialized in the same way.
So why not inject common services in a Base Controller constructor instead?
The problem with doing this on the Base Controller:
Is that it leads to this in each Child Controller:
I.e. It defeats the purpose. We still have to define our services in each Controller class constructor as the base constructor now requires them, thus forgoing the DRY Principle.
Solution
Create Properties instead
In ASP.NET Core, the Microsoft.Extensions.DependencyInjection namespace gives us access to the following extension method:
HttpContext.RequestServices.GetService<T>
Thus, we can use it to define our services as properties.
Therefore, when using common services (e.g. ILoggers) try this pattern:
Base Controller
Child Controller
Voilà. Notice how clean our code looks now. Each controller is now only responsible for injecting the services specific to them, as is the case with the PersonController and the IPersonRepository service.
Note. ILogger was just used as an example. The same pattern could be applied to the services shown in images 1–3.
Caution
Needless to say, remember to register your services in the Startup.cs → ConfingureServices method.
Also, remember that when calling these properties you are using the HttpContext object. What this means is that if the HttpContext is not yet available in the pipeline you will not be able to access your service.
E.g.