Showing posts with label DDD. Show all posts
Showing posts with label DDD. Show all posts

Sunday, March 23, 2014

Quick and Dirty Command Handlers, Event Handlers, Wiring it Up

In my last post, I talked about a "quick and dirty" way to create a command bus in F#. In this post, we're going to look at a simple set of command handlers to plug into said bus and some event handlers.

Before I jump right in, let's define what we're looking for. I want to use NEventStore for my event bus (comes with some nice features that make getting up and running much faster). Feel free to plug in whatever event store you might feel like. Creating (an extremely basic) event store isn't too terribly hard, but I am not going to cover it in this post. So, without dragging this out too much more, let's create a function that wraps up the creation of NEventStore.

Serializer

NEventStore needs a serializer. It comes with a few baked in, but I have grown fond of FsPickler. It is really fast and convenient since we're using F#. Here's a quick little helper to create our serializer on demand.

Dispatcher

NEventStore also accepts a dispatcher (the thing that is given the events as they come in). Here is where we're going to accept (for now) our event handlers. If needed, as the documentation suggests, we could fire these events off onto a bus like NServiceBus or Mass Transit. All we're going to do (again, for now) is create a function that will return a dispatcher that passes each event to our event handlers. An event handler is just a function that takes a Guid (the entity's id) and a list (ResizeArray) of events.

Create the Event Store

And, finally, we need to create the event store. There is nothing fancy here, it is pretty much just like the example documentation, just using our serializer and dispatcher. It will also use SQL Server as the backing store along with storing the streams in memory.

So, now that we have an event stream, we can push it into our command handlers and extend our setup function from the last post. We're going to change our command handler function to take in bus. We can simply map the original functions and "apply" the event bus, and then pass the resulting functions into the original "createCommandRouter" function.

A simple little domain

Let's take a look at a silly example of a domain, a counter. The counter can be incremented and decremented and that's about it. Since this is all in F#, we'll use a record to define an entity's state and discriminated union to describe the commands and events. This is a pretty common theme if you go hunting around the internet and it has worked out very well for my projects. Our entities will consist of a state, an apply function, and a handle function. (Lev Gorodinski has a really good write-up on this approach and was the basis for my personal "Ah-ha!" moment.)

Now we just need to wire-up our command handler to use the apply and handle functions. Please keep in mind that this is a "Quick and Dirty" solution to get us going and exploring our domain and wiring things up. You will likely need to a function that the handler can call if it encounters and exception and will probably need to rework the domain to return multiple events from commands and then make the appropriate changes in the command handler to handle that. (Simple, really, but too much noise for this post. I will explore these things in a later post.)

Event handlers are just as simple. They can be used to respond to events from your domain and do things like update projections that feed the application. Our "q 'n d" event handler looks something like this:

The DomainStartup

Putting this together, we now get our new domain startup.

This post is already getting long so I will end it here. Have any feedback or questions, please leave them in the comments or hit me up on Twitter. I'd love to hear how you get started quickly on projects to feel productive without building too much cruft.

Thursday, August 15, 2013

Stable Hash Codes and Abstract Base Classes

I like to use abstract base classes for my value objects. One of my most used is for identities:

public abstract class Identity<TId>
    where TId : Identity<TId>
{
    private readonly string _prefix;
    public abstract string Value { get; protected set; }

    /* ... */

    protected Identity(string value, string prefix)
        : this(prefix)
    {
        Value = value;
    }

    // So we can deserialize and have access to the prefix
    protected Identity(string prefix)
    {
        _prefix = prefix; 
    }
}

Since the identities are value objects, we need to make sure that any two identities of the same type with the same values are considered equal.

public abstract class Identity<TId> : IEquatable<TId>
    where TId : Identity<TId>
{
    private readonly string _prefix;
    public abstract string Value { get; protected set; }

    public bool Equals(TId other)
    {
        if (ReferenceEquals(null, other)) return false;
        return ReferenceEquals(this, other) || Equals(Value, other.Value);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, other)) return false;
        return ReferenceEquals(this, obj) || Equals(obj as TId);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            var hash = 17;
            hash += hash * 23 + Value.GetHashCode();
            hash += hash * 23 + GetType().GetHashCode();
            return hash;
        }
    }

    public override string ToString() { return string.Format("{0}/{1}", _prefix, Value); }

    protected Identity(string value, string prefix)
        : this(prefix)
    {
        Value = value;
    }

    // So we can deserialize and have access to the prefix
    protected Identity(string prefix)
    {
        _prefix = prefix; 
    }
}

Almost...

This works for most situations but, recently, I found out that there's a little bit of a bug with the implementation of GetHashCode(). The overall algorithm is pretty sound for most cases, minus one little piece: GetType().GetHashCode(). The way I found out this doesn't work is by having to persist the hash between uses of an app. Bringing the app down and back up caused GetType().GetHashCode() to return a different value. Whoops!

(The reason for GetType().GetHashCode() was so that two identities of different types with the same .Value; would return different hashes.)

I switched it up, for now, to use GetType().Name. Fixed the issue for me.

public abstract class Identity<TId> : IEquatable<TId>
    where TId : Identity<TId>
{
    /* ... */
    public override int GetHashCode()
    {
        unchecked
        {
            var hash = 17;
            hash += hash * 23 + Value.GetHashCode();
            hash += hash * 23 + GetType().Name.GetHashCode();
            return hash;
        }
    }
    /* ... */
}

And, to wrap up the use of this class, here's a sample of how to use it (fully serializable, too):

[DataContract(Namespace = "my-namespace")]
public abstract class ProductId : Identity<ProductId>
{
    [DataMember(Order = 1)]
    public override string Value { get; protected set; }

    public ProductId(long id)
        : base(id.ToString(CultureInfo.InvariantCulture), "product") { }

    private ProductId()
        : base("product") { }
}