Implementing an Event Driven Message Broker

An entry about arcitechture | separation of concerns Publication date 21. December 2008 20:03

Writing loosely coupled code which separates concerns is not always a simple matter of dependency inversion. Consider the following code, which shows a service responsible for creating a new user account for a website:

public class UserCreator : ICreateUsers
{
    private readonly IRepository<IUser> _repository;
    private readonly IGeneratePasswords _passwords;
    private readonly ISendCredentialsByEmail _emailSender;
 
    public UserCreator(IRepository<IUser> repository, IGeneratePasswords passwords, 
                       ISendCredentialsByEmail emailSender)
    {
        _repository = repository;
        _passwords = passwords;
        _emailSender = emailSender;
    }
 
    public IUser Create(string username, string email)
    {
        string password = _passwords.Generate();
 
        Membership.CreateUser(username, password, email);
        IUser user = _repository.FindSingle(new UserByUsernameSpecification(username));
 
        _emailSender.Send(user.Username, password, user.Email);
 
        return user;
    }
}

Do you notice any concern which is bleeding into this code, even though the actual implementation of it is separated?

When an anonymous user wishes to create an account at our site, we ask for the desired username and their email address. Upon creating the user, we auto-generate the password and send it to the given email address, enabling the user to login once he receives the email (this is so that we can verify that the new user gave us a real email address).

Apart from the concern of sending such emails bleeding into our user creation service, we’re also introducing both a possible performance issue and a  possible crash site - trying to send the email might take a long time, and the email sender might throw and exception our way if something goes wrong. Sending the email is not vital to the concern of creating the user (there’s no way we can guarantee that it gets delivered anyways), so a failure there shouldn’t cause everything else to crash.

Sure, we can get around both of these issues by rewriting our Create method a bit:

public IUser Create(string username, string email)
{
    string password = _passwords.Generate();
 
    Membership.CreateUser(username, password, email);
    IUser user = _repository.FindSingle(new UserByUsernameSpecification(username));
 
    ThreadPool.QueueUserWorkItem(m => _emailSender.Send(username, password, email));
    
    return user;
}

I don’t know about you, but that doesn’t look very elegant to me – now we’re introducing infrastructure concerns into our service. Besides, this is a very simple example – in more advanced scenarios this kind of stuff could begin to look very ugly very fast: What happens when we start to introduce more requirements, for instance? Say that whenever a user is created, a task should be added to the Administrators task list reminding him to verify and set up the any role memberships required for the new user. This would require us to further dilute the UserCreator:

public class UserCreator : ICreateUsers
{
    private readonly IRepository<IUser> _repository;
    private readonly IGeneratePasswords _passwords;
    private readonly ISendCredentialsByEmail _emailSender;
    private readonly ICreateAdminTasks _adminTaskCreator;
 
    public UserCreator(IRepository<IUser> repository, IGeneratePasswords passwords,
                       ISendCredentialsByEmail emailSender, IAdminTasksService adminTaskCreator)
    {
        _repository = repository;
        _passwords = passwords;
        _emailSender = emailSender;
        _adminTaskCreator = adminTaskCreator;
    }
 
    public IUser Create(string username, string email)
    {
        string password = _passwords.Generate();
 
        Membership.CreateUser(username, password, email);
        IUser user = _repository.FindSingle(new UserByUsernameSpecification(username));
 
        ThreadPool.QueueUserWorkItem(m => _emailSender.Send(username, password, email));
        ThreadPool.QueueUserWorkItem(m => _adminTasks.AddTask(AdminTaskType.NewUserCreated, user));
        
        return user;
    }
    
}

At this point, the UserCreator class actually contains nearly half as much code just doing concern delegation as it is actually solving what it itself is concerned with (creating the user!). What we need, is a system where we can separate not only the concerns, but the flow between them.

An Event-Driven Architecture

One way to solve this, is to implement an event-driven architecture. What that means, is basically that we enable our services to either publish or consume events which are defined within the domain model. For instance, imagine if our UserCreator published an event whenever it created a new user – then the services which need to take some action whenever this happens merely need to somehow consume this event. Of course, this requires a bit of infrastructure to get working. There are several frameworks out there which offer this functionality – most notably there’s NServiceBus, and the up-and-coming Mass Transit. However, both of these are what we call ESBs – Enterprise Service Buses. They’re probably great if you’re working on distributed applications, but personally I feel they’re a bit over the top for what I’d normally need – a simple system for messaging within the bounds of a single application. In such a scenario, I think that bog standard .NET delegates (events) will do just fine.

Rolling My Own

As a learning exercise, I decided to try rolling my own event-driven architecture infrastructure. Using it, here’s what my improved UserCreator looks like:

public class UserCreator : ICreateUsers, IPublisherOf<NewUserCreatedMessage>
{
    private readonly IRepository<IUser> _repository;
    private readonly IGeneratePasswords _passwords;
 
    public UserCreator(IRepository<IUser> repository, IGeneratePasswords passwords)
    {
        _repository = repository;
        _passwords = passwords;
    }
 
    public IUser Create(string username, string email)
    {
        string password = _passwords.Generate();
 
        Membership.CreateUser(username, password, email);
        IUser user = _repository.FindSingle(new UserByUsernameSpecification(username));
 
        Publish(new NewUserCreatedMessage(user, password));
 
        return user;
    }
    
    public event MessageEventHandler<NewUserCreatedMessage> Publish = m => { };
}

Notice how it implements the IPublisherOf interface, which is where the Publish event is coming from. Whenever the class wants to publish a message, it simply needs to raise this event. On the consumer end, I can then implement a subscriber of NewUserCreatedMessages:

public class SendNewUserCredentialsEndpoint : IConsumerOf<NewUserCreatedMessage>
{
    private ISendCredentialsByEmail _emailSender;
 
    public SendNewUserCredentialsEndpoint(ISendCredentialsByEmail emailSender)
    {
        _emailSender = emailSender;
    }
 
    public void Consume(NewUserCreatedMessage message)
    {
        _emailSender.Send(message.UserName, message.UserPassword, message.UserEmail);
    }
}

Here, I’m using the IConsumerOf interface to signal that this class wants to be notified whenever a NewUserCreatedMessage is published anywhere. And as easy as that, I’ve completely decoupled the concern of creating users from the concern of sending new users an email with their password.

How Does it Work?

To get this working, there has to be something that listens for any events that are published and forwards them to the appropriate consumers – I call this a message broker. Basically, this is the “thing” which will know about all the current publishers and consumers and how they wire together. This is where having an IOC container in charge of all the components in my application came in really, really handy, because it allowed me to implement an integration between my message broker and the container so that publishers and subscribers could be automatically discovered. All that needs to happen to make this work, is to install the MessageBrokerModule as the first module in the kernel (so that it can monitor bindings to find any consumers, and activations to find any publishers):

var kernel = new StandardKernel(
    new MessageBrokerModule(),
    new ControllerModule(typeof(PageController).Assembly),
    new ServicesModule())

With this module, whenever a binding for a component which implements the IConsumerOf interface is added to the kernel, a subscription for it will be added to the message broker. Whenever a component which implements the IPublisherOf interface is activated through the kernel, a handler for its Publish event will be created so that any messages published by it will be passed to the message broker. The fact that subscriptions are created for the bindings of consumers, means that even consumers which haven’t yet been activated (instantiated) will be so just in time to receive any messages they have requested notification of. I’m not sure if this is a common feature of an event-driven architecture (I suspect not), but it is something that I’ve found to be very useful because it makes non-singleton consumers “just work”.

Download

If you want to have a look at the code for my message broker API, you can download it here, complete with a simple example and a suite of tests. For the time being I’ve only implemented an integration with Ninject for it, but making it work with other containers shouldn’t be too hard.

The Oxitis Disclaimer: Please note that I am by no means an expert on event-driven architecture, so the message broker I’ve implemented might very well not be how the pro’s would do it.

Currently rated 4.0 by 2 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

There’s no I in Interface. Oh, wait…

An entry about arcitechture | inversion of control Publication date 7. September 2008 13:59

Last month, BDD founder Dan North visited Bergen to talk at their local NNUG event. I didn’t have a chance to attend (Bergen is a bit far; damn these Norwegian mountains :p), but I’ve talked to a few people who did and apparently it was a really good event. Jon Torresdal wrote on his blog that Dan North talked about this idea of giving the “I” prefix commonly found in C# interface names meaning:

“Dan said, why not use the I for something meaningful? Ask the interface the question: What do you do? And the interface says: ISendEmail or ISearchFiles or IPingComputers.”

I think this is a great idea. Doing this not only makes your code more expressive – it also helps you enforce the Single Responsibility Principle because it makes the concern of any given class very explicit:

public class WebFormsAuthenticator : IAuthenticateUsers
{
    public bool Authenticate(string username, string password)
    {
        return Membership.ValidateUser(username, password);
    }
}

And this not only works for any classes implementing the interfaces, but also those depending on them – it becomes especially visible if you’re using some form of dependency injection:

[Authorize(Roles="Administrator")]
public class UsersController : Controller
{
    private readonly IManageUsers _users;
    private readonly IAuthenticateUsers _authenticator;
 
    public UsersController(IManageUsers users, IAuthenticateUsers authenticator)
    {
        _users = users;
        _authenticator = authenticator;
    }
 
    /** snip **/
}

In the above example for instance, the fact that our UsersController seems to be concerned with both the managing and authentication of users is an in-your-face indication that it is possibly talking on too much responsibility (I say possibly, because it might very well be OK for it to depend on both).

I’m using this naming style in an ASP.NET MVC project I’m current working on to see how it holds up on a larger scale; so far it looks promising.

Currently rated 4.3 by 3 people

  • Currently 4.333333/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Composite Oriented Programming Redux

An entry about arcitechture | cop Publication date 25. August 2008 09:48

Back in February, as a follow-up to my exploration of Aspect Oriented Programming (part one, two, three), I took a look at Composite Oriented Programming. And then I kinda forgot about it… I remember speaking with Anders Norås at an NNUG Oslo event shortly after I had written my post, and he said he was planning to have a deeper look at COP himself; well, the other day he wrote a post about it over on his blog.

Dynapose

Back when I wrote my post I actually spent a fair amount of time implementing a C# COP framework based on my previous AOP work. So my initial post wasn’t just a theoretical “what if” kind of thing – it was actually compilable, executable code – I called it the Dynapose framework (a play on “Dynamic Composition” – clever, no? :p). The plan was to put it up on Codeplex, but I never made it that far and it just ended up collecting dust on the shelf instead. Well no more - if you want to play about with it then go to the end of this post for the download link.

Since Last Time…

In my original sample from back in February, I was using attributes as a way of configuring the composites. Later I also added a fluent interface style configuration API, which allowed composites to be dynamically built at runtime:

IDivision division = Composer.Compose<IDivision>()
                            .AddMixin<ICalculationDataAspect, CalculationDataAspect>()
                            .AddMixin<ICalculationLogicAspect, DivisionLogicAspect>()
                            .AddConcern<DivisionValidationConcern>()
                            .Instantiate();

You can also use a mix of attributes and dynamic configuration, to for example specify a default composite and then create variations of it. The fluent API will also let you give it a delegate to use as a factory method for mixins etc:

.AddMixin<ICalculationLogicAspect>(() => new DivisionLogicAspect())

My plan with this was to allow my framework to be integrated with IOC containers, which would have been totally awesome.

Known Bugs & Limitations

Well, its been a long while since I worked with this code so I’m not 100% sure on the state of things. What I do remember is that I was having a bit of trouble with generics, so that might not work as expected.

Try it Out!

If you want to play around with this yourself, then you can download the source code here. It includes a simple demo application, and the source code is fairly well documented and tested. I’ve no idea if I’ll pursue this thing any further, so take it for what it is: a fun little proof of concept project that you probably don’t want to get anywhere near your production code :p

If you do check it out, please let me know what you think, and what you made happen with it!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Pedantic About Semantics

An entry about arcitechture | thoughts Publication date 26. April 2008 22:11

Even the best of us makes mistakes. And sometimes, we don't notice 'till it's too late to turn back. This weekend, I'm working on refactoring/remodelling a fairly large feature which is part of a big legacy application at work. A seemingly innocent design decisions made years ago, has come back to haunt me, making things that should be easy difficult, and things that should just work, well, not work at all.

Years ago, the legacy application in question was party ported from unmanaged C++ into .NET. Not only that, it was ported from a flat file-based application to a database-backed application. Naturally, this created the need for a data access layer. An extension for ADO.NET was written, leveraging DataSets with all kinds of neat auto-magic features. Years of joy followed (well, disregarding the constantly growing list of reported bugs, of course).

Fast forward to present day, and finally we're getting ready to start killing off at the last bits of that old C++ code. Not only that, but we're taking on the momentous task of refactoring and cleaning up the entire application using modern-day architecture and general good-practice idioms.

Something != Nothing

Okay, so there I am, happily building a sparkling, new domain model with all the right entities in all the right places, happily staying on track with the help of Eric Evans excellent Domain Driven Design book. We've decided to use Developer Express' eXpress Persistent Objects (XPO) as our O/R mapper this time around, which among other things lets us take advantage of all the lovely new LINQ stuff (which, by the way, makes abstracting away the data access layer in unit tests a joy - look out for a post on that topic soon). So, all my tests are dressed up in their finest green and all is joy. Until I put together a simple test application to test things out against a real database... BAM! XPO blows up, complaining that the referential integrity of the database is compromised. Say what? I poke around for a bit, and quickly realise that even though the database which was modelled all those years ago and has incrementally grown to several times it's own weight since then is normalized quite well, there's something weird about these foreign keys... They've all got NOT NULL constraints. Well okay, so that might not be such a big problem in and of itself - but considering that several of the relationships are 1 <-> 0-1, this clearly poses a question of how we represent the case where, say, a Person doesn't own a Pet; what do we set the Person.PetID column to? Well, in our case, 0 is treated as the 'magic' value meaning 'nothing'. Trouble is, that's really a lie and the database doesn't know it, so it thinks that our Person really does have a pet - the pet with ID = 0. No Pet with that ID exists however, so when XPO tries to load the Person, it can't find it's Pet. Time to call the neighbours and organize a search party.

Obviously, in hindsight it makes perfect sense that the PetID column should be nullable, so that any Person who doesn't own a Pet can have Person.PetID = NULL. The difference may seem insignificant; it is however a huge difference semantically, and say one thing for computers, say they're pedantic about semantics.

Be the first to rate this post

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Mocking Revisited: Test-Driven Design

An entry about arcitechture | tdd Publication date 27. March 2008 16:27

A month or so ago, I held a talk at the local .NET user group meeting about using mocking to simplify unit testing, which I also wrote up as a post on the blog. In it, I showed both how we could manually break the dependency on some external component in order to successfully test our code in isolation, and I also did an example showing how the mocking framework Typemock Isolator could be used to get around having to refactor my code in order to test it. In this post, I'd like to revisit the example and show how the code might have looked different, had it been written using strict(ish) test-driven design principles.

Test First

When doing test-driven development, we want to focus on incrementally satisfying a single requirement at a time, ensuring the isolated correctness of each before moving on to the next. So, the first thing we need to do, is write our first test (which is the code-equivalent of a requirement):

[TestMethod]
public void NewOrderHasZeroOrderLines()
{
    Order order = new Order();
    Assert.AreEqual(0, order.OrderLines.Count);
}

Notice the Order class and its OrderLines property? We've not even declared the classes for those yet, so this test won't even compile. Following the tenents of TDD, we now want to fix that, and make the test succeed (to be pedantic, we should really make it compile and fail first, then refactor our code and make it succeed - but I won't go out of my way just to make a trivial test fail first; we'll get plenty of that later!):

public class Order
{
    private readonly List<OrderLine> _orderLines = new List<OrderLine>();
 
    public IList<OrderLine> OrderLines { get { return _orderLines; } }
}

 

Obviously, that's not how we expect our Order class to end up looking like - but for now, it satisfies all (the one) tests we have - and that means it satisfies the current requirements we have. What we do next, is add another test to verify another requirement:

[TestMethod]
public void NewOrderLineDefinesOrderLine()
{
    const int productId = 0;
    const int amount = 1;
    const decimal cost = 25;
 
    OrderLine line = new OrderLine(productId, amount, cost);
 
    Assert.AreEqual(productId, line.ProductId);
    Assert.AreEqual(amount, line.Amount);
    Assert.AreEqual(cost, line.Cost);
}

 

To pass this one, we need to refactor the OrderLine class, adding the three properties and initializing them from its constructor:

public class OrderLine
{
    public OrderLine(int productId, int amount, decimal cost)
    {
        this.ProductId = productId;
        this.Amount = amount;
        this.Cost = cost;
    }
 
    public int ProductId { get; set; }
    public int Amount { get; set; }
    public decimal Cost { get; set; }
}

 

Okay, so far the tests aren't very interresting. We're getting somewhere now, though. The original example I blogged about last time concerned itself with calculating the cost of an order. This requirement isn't straight forward to verify in a single test, as it contains several edge cases (zero orderlines, one orderline, many orderlines, etc). We should test each of these cases, then. Let's start with the simplest one first:

[TestMethod]
public void CostForZeroOrderLinesShouldBeZero()
{
    Order order = new Order();
 
    Assert.AreEqual(0, order.CalculateTotalCost());
}

 

This first one is easilly satisfiable through the following implementation of CalculateTotalCost:

public decimal CalculateTotalCost()
{
    return 0;
}

 

When we embelish upon the requirement with the following test, though...

[TestMethod]
public void CostForOrderWithSingleOrderLineShouldBeCostOfOrderLine()
{
    Order order = new Order();
    OrderLine line = new OrderLine(0, 1, 25);
    order.OrderLines.Add(line);
 
    Assert.AreEqual(line.Amount*line.Cost, order.CalculateTotalCost());
}

 

... we'll see that we need to refactor our CalculateTotalCost method to make this succeed:

public decimal CalculateTotalCost()
{
    return this.OrderLines.Sum(line => line.Amount * line.Cost);
}

 

Now that is important, what we had to do there - it is what might be said to be the essence of test-driven development, the cornerstone in the way of writing code that TDD promotes: write a test, watch it fail, then refactor to make all tests pass; rinse and repeat.

Inversion of Control

This next test that we'll be adding, will showcase how writing the code using TDD will make the end result differ in implementation from the original example. We'll be adding the idea of shipping rules; remember that this is what caused the problem in my original example because these shipping rules were to be dynamically instansiated based upon some configuration stored in a database. The CalculateShippingRule method thus needs to be able to access this configuration and get the appropriate ruleset. Thinking back to the original example, this responsibility was delegated to a static Rules class. That was what made it really hard to test, because the code then had a tight dependency on that static class, making it impossible to isolate what we wanted to test from it. Last time, I explained how the code could be refactored using a variant of the service locator pattern so that I could isolate the CalculateTotalCost method and test it properly, and I also showed how using TypeMock could let me test the original code in just a few lines of code without having to change the original implementation at all - everyone watching the presentation loved that solution, of course ;)

But here and now, since we're writing the test before implementing the feature, we're forced to think about the coupling we'll be introducing up front. We could go down the path we did last time, with a service locator - but a more natural choice for a TDD-based implementation is to choose a different implementation of the inversion of control principle called dependency injection. Basically, we'll see that our Order class will depend on some ruleset factory - so we'll add this factory as a constructor parameter on the Order class. This makes it very discoverable what the Order class is dependent on to function, but it also makes it harder to instantiate it because of the explicit dependency - anyone creating an Order instance will also need to know how to create a ruleset factory. We'll look at how to solve this problem later using an IoC container, but for now let's focus on implementing the feature. Test first:

[TestMethod]
public void CostForSingleOrderLineAndSingleShippingRule()
{
    const decimal shippingCost = 10;
 
    Mock<IShippingRule> shippingRule = new Mock<IShippingRule>();
    shippingRule.Expect(r => r.CalculateCost(It.IsAny<Order>())).Returns(shippingCost);
 
    Mock<IRules> rules = new Mock<IRules>();
    rules.Expect(r => r.Find<IShippingRule>()).Returns(new[] {shippingRule.Object});
 
    Order order = new Order(rules.Object);
    OrderLine line = new OrderLine(0, 1, 25);
    order.OrderLines.Add(line);
 
    Assert.AreEqual( line.Amount * line.Cost + shippingCost, order.CalculateTotalCost());
}

 

Last time I used TypeMock Isolator as my mocking API - I thought I'd spice things up a bit and use a different one called Moq this time. Here, I'm creating a mock of the IShippingRule interface (which I've yet to implement), setting up an expectation (using the neat lambda syntax of Moq) that basically says that "any call to CalculateCost which has an instance of an Order passed to it as the first argument, should always return the value of shippingCost (which is 10)". Next, I set up a mock for the IRules interface (which I've yet to implement, also), with an expectation that says "any call to the Find method with IShippingRule as the generic type argument should always return an array of length 1 containing the mocked IShippingRule object". Everything is then set up, so I can create an instance of my Order class, pass it the ruleset factory and excersize it by adding an orderline and calling CalculateTotalCost. Now, to pass this test we first need to make it compile by defining the interfaces we've added:

public interface IRules
{
    IEnumerable<TRuleType> Find<TRuleType>();
}
 
public interface IShippingRule
{
    decimal CalculateCost(Order order);
}

 

Secondly, we need to refactor the Order class to accept the dependency injection:

public class Order
{
    private readonly IRules _rules;
    private readonly List<OrderLine> _orderLines = new List<OrderLine>();
 
    public Order(IRules rules)
    {
        _rules = rules;
    }
 
    public IList<OrderLine> OrderLines { get { return _orderLines; } }
 
    public decimal CalculateTotalCost()
    {
        decimal sum = this.OrderLines.Sum(line => line.Amount * line.Cost);
 
        if(null != _rules)
        {
            foreach (IShippingRule rule in _rules.Find<IShippingRule>())
            {
                sum += rule.CalculateCost(this);
            }
        }
 
        return sum;
    }
}

 

Notice now, that we've completely implemented the Order class and satisfied ourselves that it works properly without having to implement any specific shipping rules or the ruleset factory to configure them. These can later be implemented and tested by themselves, and then injected into our production code as needed. And thats it, we've now got something akin in functionality to the original example - but with a slightly different implementation caused by our test-first approach; most notably we've sacrificed a bit of the simplicity to gain a more loosely coupled implementation. As explained last time, we could use a tool like TypeMock to test our original implementation, but that coupled our test much more tightly to the implementation than the testing we've been doing in this post. In the end, I'm not really sure which way to go I prefer - there are pros and cons of both that are hard to weigh up to see a clear advantage either way. I suspect there might be some golden middle road, as usual... One thing is for sure, though, there's a lot to learn here, and whichever way you choose to do it, testing will ultimately be a reward in and of itself.

Managing Dependencies

I mentioned earlier that we've introduced a level of complexity to our design by making the dependency on our ruleset factory (IRules) explicit through constructor injection. When we start getting a lot of dependencies like this, things will quickly get complicated. To solve this, we need an Inversion of Control container. Such a container takes on the job of managing and injecting the dependencies for us, so that when we want to create an instance of our Order class, we don't have to worry about the IRules instance it requires - the container will take care of it for us. There are lots of IoC container implementations out there to choose from; one which I'm really digging at the moment is Autofac. Here's how we might use it to build a container that can manage the IRules dependency for us:

var builder = new ContainerBuilder();
 
// register the ruleset factory as a singleton
builder.Register<SqlRuleSet>().As<IRules>();
 
// register the Order factory
builder.Register<Order>().FactoryScoped();
 
using(IContainer container = builder.Build())
{
    // create an order instance - the IRules dependency is 
    //automatically resolved for us by the container
    Order order = container.Resolve<Order>();
}

 

That's a quick teaser on managing dependencies using an IoC container - look out for a more in-depth post soon!

Be the first to rate this post

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Composite Oriented Programming

An entry about arcitechture | design patterns Publication date 27. February 2008 18:18

I've written a series of post on AOP lately (here, here and here), and in the last part I promised to tackle mixins and introductions in a future post. When I was doing my research for just that, I came cross a Java framework (just humor me :p) called Qi4j (that's 'chee for jay'), written by Swedish Richard Öberg, pioneering the idea of Composite Oriented Programming, which instantly put a spell on me. Essentially, it takes the concepts from Aspect Oriented Programming to the extreme, and for the past week I’ve dug into it with a passion. This post is the first fruits of my labor.

OOP is Not Object Oriented!

One of the things that Richard Öberg argues, is that OOP is not really object oriented at all, but rather class oriented. As the Qi4j website proclaims, "class is the first class citizen that objects are derived from. Not objects being the first-class citizen to which one or many classes are assigned". Composite oriented programming (COP) then, tries to work around this limitation by building on a set of core principles; that behavior depends on context, that decoupling is a virtue, and that business rules matter more. For a short and abstract explanation of COP, see this page. In the rest of this post I'll try and explain some of its easily graspable benefits through a set of code examples, and then in a future post we'll look at how I've morphed the AOP framework I started developing in the previous posts in this series into a lightweight COP framework that can actually make it compile and run.

Lead by Example

Lets pause for a short aside: obviously the examples presented here are going to be architectured beyond any rational sense, but the interesting part lies in seeing the bigger picture; imagine the principles presented here applied on a much larger scale and I'm sure you can see the benefits quite clearly when we reach the end.

Imagine that we have a class Division, which knows how to divide one number by another:

public class Division
{
    public Int64 Dividend { get; set; }
 
    private long _divisor = 1;
 
    public Int64 Divisor
    {
        get { return _divisor; }
        set 
        {
            if(value == 0)
            {
                throw new ArgumentException("Cannot set the divisor to 0; division by 0 is not allowed.");
            }
 
            _divisor = value; 
        }
    }
 
    public Int64 Calculate()
    {
        Trace.WriteLine("Calculating the division of " + this.Dividend + " by " + this.Divisor);
 
        Int64 result = this.Dividend/this.Divisor;
 
        Trace.WriteLine("Returning result: " + result);
 
        return result;
    }
}

Consider the code presented above. Do you like it? If you've followed the discussion on AOP in the previous posts, then you should immediately be able to identify that there are several aspects tangled together in the above class. We've got data storage (the Dividend and Divisor properties), data validation (the argument check on the Divisor setter), business logic (the actual calculation in the Calculate method) and diagnostics (the Trace calls), all intertwined. To what extent is this class reusable if I wanted to implement addition, subtraction or multiplication calculations? Not very, at least not unless we refactored it. We could make the Calculate method and the properties virtual, and thus use inheritance to modify the logic of the calculation - and since this is a tiny example, it would probably look OK. But again, think bigger - how would this apply to a huge API? It would easily become quite difficult to manage as things got more and more complex.

Design by Composition

With a COP framework, we can implement each aspect as a separate object and then treat them as mixins which blend together into a meaningful composite. Sounds confusing? Lets refactor the above example using an as of yet imaginary COP framework for .NET (which I’m currently developing and will post the source code for in a follow-up post), and it'll all make sense (hopefully!).

Above, we identified the four different aspects in the Division class - so let's implement each of them. First, we have the data storage:

public interface ICalculationDataAspect // aspect contract
{
    long Number1 { get; set; }
    long Number2 { get; set; }
}
 
public class CalculationDataAspect : ICalculationDataAspect // aspect implementation
{
    public long Number1 { get; set; }
    public long Number2 { get; set; }
}

In this example, the data storage is super easy – we just provide a set of properties (using the C# 3.0 automatic properties notation) that can hold the values in-memory. The second aspect we found, was the business logic – the actual calculation:

public interface ICalculationLogicAspect
{
    long Calculate();
}
 
public class DivisionLogicAspect : ICalculationLogicAspect
{
    [AspectRef] ICalculationDataAspect _data;
 
    public long Calculate()
    {
        return _data.Number1 / _data.Number2;
    }
}

Here we follow the same structure again, by defining the aspect as an interface and providing an implementation of it. In order to perform the calculation however, we need access to the data storage aspect so that we can read out the numbers we should perform the calculation on. Using attributes, we can tell the COP framework that we require this reference, and it will provide it for us at runtime using some dependency injection trickery behind the scenes. It is important to notice that we’ve now placed a constraint on any possible composition of these aspects – the DivisionLogicAspect now requires an ICalculationDataAspect to be present in any composition it is part of (our COP framework will be able to validate such constraints, and tell us up front should we break any). It is still loosely coupled however, because we only hold a constraint on the contract of that aspect, not any specific implementation of it. We'll see the benefit of that distinction later.

The third aspect we have, is validation. We want to ensure that the divisor is never set to 0, because trying to divide by zero is not a pleasant experience. Validation is a type of advice, which was introduced at length earlier in my AOP series. We've seen it implemented using the IAdvice interface of my AOP framework, allowing us to dynamically hook up to a method invocation. However, the advice we’re implementing here is specific to the data aspect, so with our COP framework we can define it as concern for that particular aspect, which gives us a much nicer implementation than an AOP framework could - in particular because of its type safety. Just look at this:

public abstract class DivisionValidationConcern : ICalculationDataAspect
{
    [ConcernFor] protected ICalculationDataAspect _proceed;
 
    public abstract long Number1 { get; set; }
 
    public long Number2
    {
        get { return _proceed.Number2; }
        set
        {
            if (value == 0)
            {
                throw new ArgumentException("Cannot set the Divisor to 0 - division by zero not allowed.");
            }
 
            _proceed.Number2 = value; // here, we tell the framework to proceed with the call to the *real* Number2 property
        }
    }
}

I just love that, it's so friggin' elegant ;). Remember that an advice is allowed to control the actual method invocation by telling the target when to proceed – we’re doing the exact same thing above, only instead of dealing with a generic method invocation we're actually using the interface of the aspect we're advising to control the specific invocation directly. In our validation, we validate the value passed into the Divisor setter, and if we find it valid then we tell the target (represented by a field annotated with an attribute which tells the COP framework to inject the reference into it for us, much like we did with aspects earlier) to proceed with the invocation; otherwise we throw an exception. This particular concern is abstract, because we only wanted to advise a subset of the methods in the interface. That's merely a convenience offered us by the framework - under the covers it will automatically complete our implementation of the members we left abstract.

Only one aspect remains now, and that is the logging:

public class LoggingAdvice : IAdvice
{
    public object Execute(AdviceTarget target)
    {
        Trace.WriteLine("Invoking method " + target.TargetInfo.Name + " on " + target.TargetInfo.DeclaringType.FullName);
 
        object retValue;
 
        try
        {
            retValue = target.Proceed();
        }
        catch(Exception ex)
        {
            Trace.WriteLine("Method threw exception: " + ex.Message);
            throw;
        }
 
        Trace.WriteLine("Method returned " + retValue);
 
        return retValue;
    }
}

We’ve implement it as a regular advice, like we've seen earlier in AOP, because it lends itself to much wider reuse than the validation concern did.

Having defined all our aspects separately, it is now time to put them back together again into something that can actually do something. We call this the composite, and it is defined as follows:

[Mixin(typeof(ICalculationDataAspect), typeof(CalculationDataAspect))]       
[Mixin(typeof(ICalculationLogicAspect), typeof(DivisionLogicAspect))]
[Concern(typeof(DivisionValidationConcern))]
[Concern(typeof(LoggingAdvice))]
public interface IDivision : ICalculationDataAspect, ICalculationLogicAspect 
{ }

Basically, we’ve just defined the implementation of an interface IDivision as a composition of the data and logic aspects, and sprinkled it with the two concerns (the validation concern and the logging advice). We can now use it to perform divisions:

IDivision division = Composer.Compose<IDivision>().Instantiate();
division.Number1 = 10;
division.Number2 = 2;
 
Int64 sum = division.Calculate();

That’s pretty cool, no? Take a moment to just think about what doors this opens. To what extent do you think our code is reusable now, if we wanted to implement addition, subtraction and so forth? That’s right – all we’d need to do is substitute the implementation of the calculation aspect with one that performs the required calculation instead of division, and we're done. Let’s do subtraction, for example:

public class SubtractionLogicAspect : ICalculationLogicAspect
{
    [AspectRef] ICalculationDataAspect _data;
 
    public long Calculate()
    {
        return _data.Number1 - _data.Number2;
    }
}

That’s it! The rest we can reuse as is, building a new composite:

[Mixin(typeof(ICalculationDataAspect), typeof(CalculationDataAspect))]
[Mixin(typeof(ICalculationLogicAspect), typeof(SubtractionLogicAspect))]
[Pointcut(typeof(LoggingAdvice))]
public interface ISubtraction : ICalculationDataAspect, ICalculationLogicAspect
{ }

Notice that we just left out the validation concern in this composite, as it is no longer needed. What if we wanted our subtraction to only ever return positive numbers? Easy! We’ll just implement an absolute number concern:

public class AbsoluteNumberConcern : ICalculationLogicAspect
{
    [ConcernFor] protected ICalculationLogicAspect _proceed;
 
    public long Calculate()
    {
        long result = _proceed.Calculate();
 
        return Math.Abs(result);
    }
}

And then update the composition to include it:

[Mixin(typeof(ICalculationDataAspect), typeof(CalculationDataAspect))]
[Mixin(typeof(ICalculationLogicAspect), typeof(SubtractionLogicAspect))]
[Concern(typeof(AbsoluteNumberConcern))]
[Pointcut(typeof(LoggingAdvice))]
public interface ISubtraction : ICalculationDataAspect, ICalculationLogicAspect
{ }

To Be Continued…

I hope this post has whet your appetite for more on this subject, as I will certainly pursue it further in future posts. I’ve already implemented a prototype framework that supports the above examples, which builds on my previously posted AOP framework, and I’ll post the source code for that soon. If you want to dig deeper right now (and don’t mind a bit of Java), then I suggest you head over to the Qi4j website and poke about there. Richard Öbergs blog also provides great insight.

Currently rated 5.0 by 3 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Powered by BlogEngine.NET 1.4.5.0

Welcome!

My name is Fredrik Kalseth, and this is my blog - thanks for visiting! I am fortunate enough to work with what I love for a living, and this blog is essentially the biproduct of that.

I work as a senior consultant for Capgemini, and am also an active participant in the Norwegian .NET community, as an avid attendee but also as a speaker (most recently at NNUG and MSDN Live).

As a developer, I have a wide circle of interest. My primary passion is for agile, test-driven development, with focus on best practices and clean code. That said, I also love to work on the frontend, especially with web development.

On Twitter? My handle is fkalseth. On LinkedIn? I`m there too.

Disclaimer

This is a personal blog; any opinions expressed here are my own and do not necessarily reflect those of my employer. All content herein is my own original creation, and as such is protected by copyright law. Unless otherwise stated, all source code posted on this blog is freely usable under the Microsoft Permissive License.

What Readers Talk About

Comment RSS