Register Decorator In Microsoft Dependency Injection

The guide shows how to register a decorator pattern in Microsoft Dependency Injection framework

Wednesday, November 20, 2019

The Decorator Pattern

For the purpose of the guide let's have following code structure

In above example, HttpService is being decorated by LoggingService as both implement common interface and logging service wraps the HTTP service with added functionality.

Microsoft Dependency Injection

Unlike other dependency injection frameworks such as Unity or Castle Windsor, Microsoft Dependency Injection doesn't natively support circular dependency - notice that LoggingService implements IService and at the same time accepts IService in the constructor.

Unless you want to implement workarounds, the obvious solution is to use the rather mentioned Unity or Castle Windsor that supports decorator patterns out of the box. In case this is not an option for you, fortunately, an alternative exists - let's break the circular dependency with the flagging interface!

Flagging Interface For The Rescue

By using flagging interface we can break the circular dependency so that LoggingService implementing IService no longer accepts IService in the constructor. Let's take a look on the code snippet

Above we no longer have circular dependency. LoggingService Implementing IService injects now IHttpService. IHttpService is adding no additional signatures, it serves purely as flag of the specific service.

Now we can use the native functionality of the Microsoft Dependency Injection freely and will achieve decorator functionality.

Beneficial Side Effect

Depending on your needs, the flagging interface might not be an option for you. Personally, I faced very few use cases when the usage of the flagging interface was not an option.

Additionally, the flagging interface brings a specific feature to the table - you define the order of decorations by design. In other words, you are explicitly stating in decorator class what type of interface you want to decorate by specifying concrete injected flagging interface. As an example let's imagine HTTP service, logging service, and caching service. You want to achieve execution in a specific order of logging service -> caching service -> HTTP service. By specifying the expected injected flagging interface, you no longer rely on the IoC configuration itself, instead, you have it strongly typed in the code design.

Closing Notes

I hope you found the flagging interface helping with decorator patterns a useful alternative to the workaround packages or techniques. In case you want to use the Microsoft Dependency Injection framework and want to inherit a common interface, there are workarounds available as e.g. Scrutor.