In the previous post we started building an extension to our DDD skeleton project. We saw a simple way of adding a component to the TimetableService so that we could send an email upon inserting or updating a load test. We also discussed the pros and cons of the current implementation.

We discussed the decorator in a dedicated post referenced above. In short this pattern aims to extend the functionality of objects at runtime. It achieves this goal by wrapping the object in a decorator class leaving the original object intact. The result is an enhanced implementation of the object which does not break any client code that’s using the object.

The pattern has various forms of implementation. We’ll go for the approach where the decorator implements the abstraction and also has a dependency on the same abstraction type. In our case we’ll have a new implementation of ITimetableService which also has a dependency of type ITimetableService. The “inner” ITimetableService will perform the actual job of the timetable service, i.e. the tasks we have in TimetableService.cs. The “outer” ITimetableService will also require an IEmailService. It delegates all the “real” job related tasks to the inner service and calls upon the email service upon load test job insertions or updates. Insert the following class TimetableServiceWithEmail into the Implementations folder of the ApplicationServices layer:

As you can see the DeleteLoadtestAsync and GetLoadtestsForTimePeriodAsync methods are simply delegated to _innerTimetableService. The real work of AddOrUpdateLoadtestsAsync is also forwarded to _innerTimetableService. When it returns we check if there’s anything new to tell the world about. If that’s the case then we call upon _emailService to send the email.

Decorator in StructureMap

The next technical step is to wire up the enhanced decorator with StructureMap so that it is injected into LoadtestsController. If you run the project now TimetableServiceWithEmail won’t be picked up of course as it doesn’t follow the default interface implementation naming convention. However, TimetableServiceWithEmail also requires an ITimetableService.

Fortunately that’s not a brand new software requirement and there’s a clean solution for that in StructureMap. Open DefaultRegistry.cs in the DependencyResolution folder of the WebApi project. Currently we have the following line under the Scan method call:

For<IEmailService>().Use<FakeEmailService>();

Remove that row and add the following instead:

For<ITimetableService>().Use<TimetableService>().DecorateWith(i => new TimetableServiceWithEmail(i, new FakeEmailService()));

I know it looks weird, but it works.

You can test the solution by adding one or more new loadtests like we did before – you can refer to this post how to do that. You’ll see that the decorator is called as expected.

There you have it, this is an application of the decorator pattern to enhance the functionality of the original TimetableService implementation of the ITimetableService interface.

Can we be satisfied yet? It depends on what you’d like to achieve. It is possible that inserting or updating a load test is such an important event that we don’t simply want to send an email but perform a whole range of other things. In fact there might be other systems out there that want to be notified of such an event, e.g. a Windows service that’s going to execute the load test, or some other scheduling system that will send out automated emails 1 hour before the test starts to all parties involved.

Coordinating such systems is difficult to achieve with decorators only. There’s a number of solutions to enable this type of communication. We’ll look at an example of messaging starting in the next post. We’ll also learn about another concept of Domain Driven Design: domain events.