Decorator pattern with C# and DotNet Core

What is decorator pattern and how to use it in your core applications

Mon, 01 Apr 2019

Banner

Introduction (Background)

I have a habit that i learn new patterns or technologies if i really need them to solve my problems or make my life easier as developer. Few months back i was working on Some .Net Core We were using the CQRS patterns for that application and we had the requirement to generate notification when some of the commands are successfully executed.

I was trying to solve these problems with minimal amount of code duplication and wanted to minimal amount of refactoring. In my opinion generating notifications should not be the responsibility of a Command and should not belong in the body of commands to maintain the single responsibility principle.

There was some time before we had to start the actual implementation. Then one day i was watching a pluralsight course about CQRS In Practice and author of the course discussed the similar issue and demonstrated a really interesting approach to solve the above issue. The author of the course introduced the Decorator problem to solve the above issue and that was exactly what i was looking for. So i started my journey to explore more about the decorator pattern. On connecting dots i found out that it is vary commonly used pattern in other languages like Javascript. It reminded me of the time few years back when i used react-redux ‘connect’ decorator to connect components to the redux store so i used that pattern without even knowing that it is a decorator pattern. I decided to document my learning of Decorator pattern while i explore more about it in the hope that someone else in the community can benefit from it.

Let’s give the credit where it is due. This post is highly inspired from the Pluralsight course CQRS in Action. If you have Pluralsight subscription i will highly recommend that course. Definitely one of my favorites.

Decorators - What it is?

Decorators are very similar to Aspect Oriented Programming(AOP) in terms of benefits. Here is what i think of Decorator pattern in very simple terms

In very simple terms Decorator is a class which enhance/change the functionality of other class. Without modifying the original class.

First the Problem and Solution of the Problem

Usually the explanation about the Decorator Pattern usually starts with theory first then the code samples. But I always have a problem first then i start looking for different ways to solve that problems then look at the cost and the benefits. We will try to follow the same pattern in this blog post and we will discuss the problem first. Then we will look at the solution and then we will discuss the other options and talk about the cost and benefits.

Code Used in this Post

All the code samples from this post can be found. In git repo if you want to follow along i will highly recommend please clone or download the Code from repository. In this code repository i created a very simple example of an API for a TODO app. Even it is a very basic project but i think it will be sufficient enough to demonstrate the Decorator pattern. I assume you have basic understanding of CQRS pattern. But don’t worry if you don’t please read through the Code attached and you will be able to make sense of the most of the code in repo. If something is not clear please let me know in comments. So once again i will highly recommend to clone the Repo and have a read through the code before you proceed.

Problem to Solve

Let’s to keep the first example simple lets assume you want to Audit Log successful execution of a command in your system. As a basic CQRS pattern implementation we have following contracts in our code (Check the Code from Git Repo).

  • ICommand - Interface to Represent data for a command

  • ICommand<TCommand> - Interface to represent all the Handlers that can handle a command if provided with ICommand and Conatins the method Handle(TCommand) where TCommand is of type ICommand

So that’s pretty much we have Commands and Command Handlers. Each Command have corresponding Command Handler. In our test case Let’s Assume we have Command to Change the Status of a TODO item and name of the command is ToggleItemCommand and it’s handler is ToggleItemCommandHandler.

Our contracts for ICommand and ICommandHandler looks like belo

    public interface ICommand
    {
    }
    //Interface to represent a Handler that can Execute or Handle a command object
    public interface ICommandHandler<TCommand>
        where TCommand : ICommand
    {
        Result Handle(TCommand command);
    }

Now let’s have a look at the command To toggle the status of a TODO Item. It implements the ICommand interface.

//Actual command class to represent the variable that 
//Command will accept
public class ToggleItemCommand: ICommand
    {
        //Id for the Item to be updated
        private int Id {get;}
        //New done status for the item.
        private bool Done {get;set;}

        public ToggleItemCommand(int id, bool status)
        {
            Id = id;
            Done = status;
        }
        // In ideal scenario this handler should be an internal class
        //But for now let's leave it public
        public sealed class ToggleItemCommandHandler: ICommandHandler<ToggleItemCommand>
        {
            private readonly IRepository repository;

            public ToggleItemCommandHandler(IRepository repository)
            {
                this.repository = repository;
            }

            public Result Handle(ToggleItemCommand command)
            {
                var item = repository.GetById<TodoItem>(command.Id);
                if(item == null)
                {
                    return Result.Fail($"No Item found with Id: {command.Id}");
                }
                item.IsDone = command.Done;
                if (command.Done)
                {
                    item.CompleteDate = DateTime.UtcNow;
                }
                repository.Update<TodoItem>(item);
                return Result.Ok();
            }
        }
    }

So we want to enhance the CommandHandler so that If the command is completed successfully we need to perform some additional action that means log some extra information or anything.

I can create a wrapper class that wrap command Handlers into some sort of Top Level class(Decorator Class) New class that implement the Same Contract(ICommandHandler) as the original Command Handlers and then i can Inject the Additional Code and without modifying the original CommandHandler handle method. That’s a lot of talk let’s see it in action now. I assume few examples will help to understand what i was trying to convey. I added some comments to code examples to explain the code.

//Implementing the same Interface as any other handler `ICommandHandler`
public sealed class AuditLoggingDecorator<TCommand> : ICommandHandler<TCommand>
        where TCommand : ICommand
    {
        private readonly ICommandHandler<TCommand> _handler;
        //Receive original command handler as input parameter to constructor
        public AuditLoggingDecorator(ICommandHandler<TCommand> handler)
        {
            _handler = handler;
        }
        //New version or enhanced version of the Command Handler
        public Result Handle(TCommand command)
        {
            //Create JSON representation of the Command Recieved
            string commandJson = JsonConvert.SerializeObject(command);

            // Log the Contents of the Commmand
            Console.WriteLine($"Command of type {command.GetType().Name}: {commandJson}");
            //Call the Handler method of the original CommandHandler
            return _handler.Handle(command);
        }
    }

In this example we created very simple decorator that will Just serialize a command and then log it. But in real world you can create decorator to achieve something like Database Retries or generate notification for successful execution of few commands. For example when ever a Listing get updated trigger the Elastic Search Indexing for the record.

No we have a wrapper class that can audit log every command. But how we can use it in our asp.net core application. All we have to do instead injecting the actual CommandHanlder we can inject the Decorated CommandHandler. If you are using the out of box dependency injection for ASP.NET Core here how you can use it without using any third party libraries. In this example we are injecting the ToggleItemCommandHandler

//Don't worry if it looks like a mess. We will simplify it later in the post.
services.AddTransient<ICommandHandler<ToggleItemCommand>>(provider => 
                new AuditLoggingDecorator<ToggleItemCommand>(
                    new ToggleItemCommand.ToggleItemCommandHandler(
                        provider.GetService<IRepository>()
                        )
                    )
              );

//Lets break it down
//Step 1: Create new instance of ToggleItemCommandHandler- new ToggleItemCommand.ToggleItemCommandHandler(provider.GetService<IRepository>())

//Step 1.1: Get the repository for  Command Handler using DI container - Assume it is already configured (provider.GetService<IRepository>())

//Step 2: Wrap the Command Handler from Step 1 into Decorator -  new new AuditLoggingDecorator<ToggleItemCommand>(HANDLER_FROM_STEP_1);

//Step 3: provider =>  Create factory  factory to return wrapped CommandHandler.

//Step 4: Configure DI container to use Factory from Step3 every time someone request command Handler for EditPersonalInfoCommand - services.AddTransient<ICommandHandler<EditPersonInfoCommand>>(factory);

Let’s try to simplify the above example let’s extract the Factory to a method and few readers may find it more readable.

//Here is a verbose version where we extracted the method to create factory
//Then used the method to register the factory
// Simplified/verbose code to return  factory.
private static Func<IServiceProvider, ICommandHandler<ToggleItemCommand>> GenerateToggleItemCommandFactory()
        {
            Func<IServiceProvider, ICommandHandler<ToggleItemCommand>> factory = (IServiceProvider provider) =>
            {
                //Get repository from DI Container
                var repository = provider.GetService<IRepository>();
                //Create command handler using the Repository
                var handler = new ToggleItemCommand.ToggleItemCommandHandler(repository);
                var decorated = new AuditLoggingDecorator<ToggleItemCommand>(handler);
                return decorated;

            };
            return factory;
        }
//Configure the Factory for injection.
services.AddTransient<ICommandHandler<ToggleItemCommand>>(GenerateToggleItemCommandFactory());

If we look at the code above it still look very complex and lack readability. Assume you have 10 different command you have and you want to Decorate each them using approach the thing will get complicated really soon. In the next post i will discuss about how we can make it bit more stream line using the Attributes and Reflection.

We had a problem we solved the problem. But how the above solution fit as a Decorator Pattern. We we will discuss in next section Theory.

Theory

Let’s start with a sort of text book definition of decorator patter.

In object-oriented programming, the decorator pattern is a design pattern that allows behavior to be added to an individual object(ICommand In our scenario), dynamically, without affecting the behavior of other objects from the same class.

So we added additional Behavior to ICommand without using actually effecting the Behavior of other objects from the same class.

In theory The classes and objects participating in this pattern are:

  • Component(ICommandHandler): defines the interface for objects that can have responsibilities added to them dynamically.
  • ConcreteComponent(ICommandHandler<ToggleItemCommand>) defines an object to which additional responsibilities can be attached.
  • Decorator Maintains a reference to a Component object and defines an interface that conforms to Component’s interface.
  • ConcreteDecorator(AuditLoggingDecorator<TCommand>) adds responsibilities to the component.

We had a look at a problem and then we solved the problem using the Decorator Pattern. Then validated our solution against the definition of the Decorator Pattern and Highlighted the various components involved. Next we will look at how the Decorator Pattern is similar to ASP.NET Core middleware.

How Decorator patterns is similar to ASP.NET Middleware

If we look carefully Decorating command or query handlers with Decorator Pattern look very much like the Middleware infrastructure of ASP.NET. In my opinion they implement the same Decorator Pattern but with slight changes. In the case of ,ASP.NET middleware we do not have common interface like ICommandHandler<>. ASP.Net use reflection to call the Invoke on the each middleware configure for the pipeline. Another similarity is the parameters accepted by both.

  • Our decorator accepts the Class to enhance or the next function to call.
  • Middleware accept next middleware in the pipeline and call the Invoke method on it.

And both of them add extra functionality on the top and call the next method.

If you ask my opinion. ASP.NET Core middleware implements the Decorator Pattern. Next question is where each of them should be used.

Why choose one or other

First thing come to my mind after considering all these similarities. Why do we even need the Decorator Pattern in our applications. Why can’t we use the middleware all the time that is provided out of the box by Microsoft. Here is why i think using Middleware everywhere is not a great idea.

  • Middleware infrastructure is part of ASP.NET framework. I am not big fan of adding framework dependent patterns to your application in the layers(Core or Logic) that has nothing to do with ASP.NET.
  • Decorator provides better over how the infrastructure you have better control over Context, Parameters and order of invocation.
  • More specific in terms of it is easy to apply them on a particular CommandHandler you can even decide on the runtime what Decorators and in which order they should be applied.

Middleware is good for cross-cutting concerns that are ubiquitous and ASP.NET related. The exception handler is a nice example of here. Because we want it to run on every controller in our application. We want it to handle all unhandled exceptions, and it also takes care of ASP.NET related concerns. It converts all unhandled exceptions into 500 responses, which correspond to internal server errors.

Anything else that is not ASP.NET related Middleware option will be more flexible and provides more control.

Conclusion

In this post we looked at a problem. Then we considered how Decorator Pattern helped us solved that problem without too much refactoring and avoided code duplication. Then we looked at how we can use Decorator Pattern with .NET core applications. Then we discussed the similarities between the Decorator pattern and .NET middleware and why and when we choose one another. Our implementation of Decorator Pattern was good for a blog post example and will not scale very well for most production applications. In next post we will have a look how we can simplify the code making use of Attributes and .NET core DI. Till then good bye and see you later. I you like my writings and interested in hearing more from me you can follow me on Twitter.

Loading...
Ranjeet Singh

Ranjeet Singh Software Developer (.NET, ReactJS, Redux, Azure) You can find me on twitter @NotRanjeet or on LinkedIn at LinkedIn