Decorator Pattern using a Dependency Injection Container

Here we go again, this time I will show you an example about how to implement the decorator pattern using a DI container, in this case I will use Simple Injector . I have been working with this container at the office and it has worked really well, it is well documented and has a good performance.

In the following example I will add the logging functionality to my application using the decorator pattern, let’s start:

STEP 1:

Create an interface

public interface IApplicationFacade
    {
        int Sum(int number1, int number2);
    }

Step 2:

Create a concrete class implementing the interface

public class ApplicationFacade : IApplicationFacade
    {
        public int Sum(int number1, int number2)
        {
            return number1 + number2;
        }
    }

Step 3

Create abstract decorator class implementing the Application facade interface.

public abstract class ApplicationFacadeDecorator : IApplicationFacade
    {
        private readonly IApplicationFacade _applicationFacade;

        public ApplicationFacadeDecorator(IApplicationFacade applicationFacade)
        {
            _applicationFacade = applicationFacade;
        }

        public virtual int Sum(int number1, int number2)
        {
            return _applicationFacade.Sum(number1, number2);
        }
    }

Step 4

Now we need to create a concrete decorator class extending the ApplicationFacadeDecorator class. In this case this class will add the logging functionality to the application facade class.

public class LogApplicationFacade : ApplicationFacadeDecorator
    {
        public LogApplicationFacade(IApplicationFacade applicationFacade)
            : base(applicationFacade)
        {
        }

        public override int Sum(int number1, int number2)
        {
            Log("Method Sum Called");
            return base.Sum(number1, number2);
        }

        private void Log(string message)
        {
             Debug.WriteLine(message);
        }
    }

Step 5

Now we have to configure the DI container.  We will register the types as follow:

container.Register<IApplicationFacade, ApplicationFacade>();

container.RegisterDecorator(typeof(IApplicationFacade),
                      typeof(LogApplicationFacade));

Step 6

Now we have just to call the sum method in our application facade class. In this case I am using an MVC application, so the controller will look like this:

public class HomeController : Controller
    {
        private readonly IApplicationFacade _facade;

        public HomeController(IApplicationFacade facade)
        {
            _facade = facade;
        }

        // GET: Home
        public ActionResult Index()
        {
            var result = _facade.Sum(1, 1);
            return View(result);
        }
    }

Now the execution will pass first for the sum method in the class LogApplicationFacade , it will log the message and then will go to perform the sum operation returning the result.

We can add more than one decorator to a class, for example, we could add another decorator like a validation decorator to the application facade class , this way we will be able validate for example that the result isn’t greater than 2.

Another variation that we could add to this that maybe could be useful is the possibility of disabling a decorator depending of a key in our web.config for example. We can perform this in our DI container configuration like this:

bool addLogDecorator = Convert.ToBoolean(ConfigurationManager.AppSettings["AddLogDecorator"]);
            if (addLogDecorator)
            {
                container.RegisterDecorator(typeof(IApplicationFacade),
                      typeof(LogApplicationFacade));
            }

In this case if the key “AddLogDecorator” is false the decorator will not be applied and the execution of the method will bypass this decorator class and it will go directly to the sum method in the application facade.

You can find the code of this example in my Github

Thanks for reading

Advertisements
This entry was posted in Architecture and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s