.NET Core Dependency Injection —Decorator Workaround

Willie Tetlow
2 min readJul 30, 2017

--

I’ve been learning about Domain Driven Design and applying Command Query Separation (CQS) at an architectural level. The Decorator Pattern, using dependency injection (DI), works well with CQS but .NET Core’s dependency injection doesn’t have any nice functionality to register these decorators. I wanted a way to decorate my Command and Query handlers without adding a different DI library, that was readable and allowed me to define the decoration structure once.

CQS and Decorators

I’m going to brush over the concepts of using CQS to structure an application but to give you some background, here is a basic example of a query and query handler.

Query.
Query Handler.

It’s important to note, that once we define a number of queries we’re going to have all their handlers implementing the same interface. This allows us to define a class that takes an implementation in its constructor, performs an action, and returns the result of the passed in handler… A Decorator!

We can use decorators to reduce the amount of cross-cutting concerns creeping up in code and satisfy DRY and Open/Closed principles. A good example is a class that logs every time a query is called.

Logging Decorator.

Decorators with Dependency Injection

Using the built-in dependency injection to define a decorator structure was far too intricate. I had to write the decoration code for each handler, it wasn’t easily readable and it was clogging up the startup file.

Example Decoration in Startup.

You can see from the example, there’s too much code to write for every query. It goes against DRY and Open/Closed principles, removing the benefit of using decorators! (If we need to change the decoration structure there’s a lot of code we need to touch)

I’d read a post about using extension methods to register dependencies and declutter the startup file and thought I could use the same pattern for defining decorator structures.

Declaring a Decorator Structure.

This extension method takes the query handler, query and result types, using generics:

RegisterQueryHandler<TQueryHandler, TQuery, TResult>

Then registers the query handler:

services.AddTransient<TQueryHandler>();

This is so we don’t have to add the services (if any) to the handler’s constructor ourselves. We depend on .NET Core’s DI instead.

Then define the decoration structure, injecting an instance of the query handler into the decorator:

services.AddTransient<IQueryHandler<TQuery, TResult>>(x =>
new LoggingDecorator<TQuery, TResult>(
x.GetService<ILogger<TQuery>>(), x.GetService<TQueryHandler>()));

The RegisterQueryHandler method increases the readability of the startup file and allows easy identification of the registering of queries and their handlers.

Example usage:

I much prefer this simple solution to using another DI library. The logic is encapsulated in one file and we could even use a strategy for different decorations. All without adding another dependency to the codebase, .NET Core only!

If you still want to use .NET Core’s DI but would prefer to use a package with a similar syntax to other DI libraries, there’s this great open-source project, Scrutor.

--

--

Willie Tetlow

Senior Frontend Engineer at Shogun, Javascript and Functional Programming.