Saturday 16 March 2013

CQRS in Scala: Commands

I have been working with the CQRS pattern in C# for a while, and about a year ago have been implementing it in Scala.  Over the last year I have been simplifying down my approach. Please, any comments, suggestions or criticism are most welcome. It assumes knowledge of the principles of CQRS.  You might also find this post helpful 

The following implementation does not yet take into account events, however this will be covered.

First we have a trait to mark a command
trait Command


Individual command will implement this trait, such as

case class NewUserCommand(string:Login, string:Password) extends Command


For each command there should be a handler which will extend the following:

trait Handler[T <: Command] {
  def handle(command:T):Unit
}

The command handlers I use follow the cake pattern, and have state wired in.  For example

trait NewUserCommandHandler extends Handler[NewUserCommand] {
  this:SecurityService with PersistencyService =>

  def handle(command:NewUserCommand) { ... }
}

In this example state is a document cache required by the PersistencyService:

trait DocumentPersistencyService extends PersistencyService {
  def state:DocumentCache

  ...

I have created a registry for holding the constructor of the command handlers.  Here state is a type parameter, though I don't think that's entirely necessary. The registry is mutable only until first use, I have followed the same approach that I used here.

trait CommandRegistry[State] {
  def getHandler[T <: Command:TypeTag](implicit state:State):Handler[T]
}

trait CommandConstructorRegistry[State] extends CommandRegistry[State] {

  private val registryBuffer = new ListBuffer[(TypeSymbol, (State) => Handler[_])]
  private lazy val registry = registryBuffer.toMap

  def getHandler[T <: Command:TypeTag](implicit state:State):Handler[T] = registry(typeOf[T].typeSymbol.asType)(state).asInstanceOf[Handler[T]]

  def register[T <: Command:TypeTag](constructor:((State) => Handler[T])) {
    registryBuffer += ((typeOf[T].typeSymbol.asType, constructor))
  }
}

A command dispatcher wraps this all up, so that all commands can be issued via the dispatcher.

trait CommandDispatcher[State] {

  def dispatch[T <: Command:TypeTag](command:T)(implicit state:State):Unit
}


trait DefaultCommandDispatcher[State] extends CommandDispatcher[State] {
  this:CommandRegistry[State] =>
  def dispatch[T <: Command:TypeTag](command:T)(implicit state:State) {
    val handler = getHandler[T]
    handler.handle(command)
  }
}

So tying it all together looks something like this:

val commandDispatcher = new DefaultCommandDispatcher[DocumentCache] with CommandConstructorRegistry[DocumentCache] {
  register(s => new NewUserCommandHandler with DefaultSecurityService with DocumentPersistencyService { val state = s })
}

implicit val state = new DocumentCache()
val command = NewUserCommand("login","password")
commandDispatcher.dispatch(command)

You could also enrich the dispatcher through the use of mixins, say if you wanted to log the commands content:

trait CommandLogger[State] extends CommandDispatcher[State] {
  
  abstract override def dispatch[T <: Command:TypeTag](command:T)(implicit state:State) {
    println(command)
    super.dispatch(command)
  }
}

Thursday 7 March 2013

Scala 2.10 Simple DI Container

I have been finding the use of a container object still quite handy, despite use of the cake pattern.  Mostly I have used it to return singletons and dependency injection.  Using Scala 2.10 reflection, I have developed a simple container for my requirements. This has been handy in getting the basics of the new reflection libraries, in particular, generating an item from its constructor method.  My other goal was to make the container functional, hence transparent and immutable, I believe I pretty much achieved that, though am open to criticism.
So first the container trait:

trait Container {
  def get[T:TypeTag]:T

  def get[T:TypeTag](args:Any*):T
}

This methods return an instance of Type T, the second of which allows external dependencies to be injected.
Next is a trait for binding classes. The idea is that a list of types or instances will be registered for the containers use. The bind methods will attach all base classes of the registered type or instance as well, excluding Any or Object. If the same class or base class has already been registered, the latest bind will dominate. Bind occurs in the constructor, making the result effectively immutable.
By using the function bindAt, only the specified, or instance level class will be registered against the instance. So a binding trait extension looks something like this:

trait BoundElements extends Bindings {

  bind[ClassA]
  bind[ClassB]
  bind(new InstanceA()]
  bindAt[BaseClassB](new InstanceB()]
}

This is achieved by storing the bindings in private list buffers which are then access through a lazy evaluated immutables map. The bindings trait is as follows:

trait Bindings {
  private val bindingsBuffer = new ListBuffer[(TypeSymbol, (ClassSymbol, MethodSymbol))]
  private val instanceBuffer = new ListBuffer[(TypeSymbol, Any)]
  private val excluded:Set[Symbol] = Set(typeOf[Any].typeSymbol, typeOf[Object].typeSymbol)

  protected lazy val registry:Map[TypeSymbol, (ClassSymbol, MethodSymbol)] = bindingsBuffer.toMap
  protected lazy val instanceRegistry:Map[TypeSymbol, Any] = instanceBuffer.toMap

  protected def bind[T:TypeTag]() {
    val types = getBaseTypes[T]
    val ctor = getConstructor[T]
    bindingsBuffer ++= types.map((_ -> (typeOf[T].typeSymbol.asClass, ctor)))
  }

  protected def bind[T:TypeTag](instance:T) {
    val types = getBaseTypes[T]
    instanceBuffer ++= types.map((_ -> instance))
  }
  protected def bindAt[T:TypeTag](instance:T) {
    instanceBuffer += (typeOf[T].typeSymbol.asType -> instance)
  }

  private def getBaseTypes[T:TypeTag] = {
    val base = typeOf[T].baseClasses.map(_.asType)
    base.filter(!excluded.contains(_))
  }

  private def getConstructor[T:TypeTag] = typeOf[T].members.filter(_.isMethod).map(_.asMethod).filter(_.isConstructor).head
}

The next trait is the dependency injector, it requires bindings and extends the container trait.  In this case it will only use the first listed constructor. The Dependency injector constructs the required classes, or if they are already instances, provides them.

trait DependencyInjector extends Container {
  this:Bindings =>

  def get[T:TypeTag]:T = getInstance(typeOf[T].typeSymbol.asType).asInstanceOf[T]

  def get[T:TypeTag](args:Any*):T = getInstance(typeOf[T].typeSymbol.asType, args.toSet).asInstanceOf[T]

  protected def getInstance(typeSymbol:TypeSymbol, args:Set[Any] = Set.empty):Any =
    args.find(a => currentMirror.reflect(a).symbol.toType <:< typeSymbol.toType).getOrElse{
      instanceRegistry.getOrElse(typeSymbol, {
        val (clazz, ctor) = registry(typeSymbol)
        val ctorArgs = ctor.asMethod.paramss.head map (p => getInstance(p.typeSignature.typeSymbol.asType, args))
        currentMirror.reflectClass(clazz).reflectConstructor(ctor).apply(ctorArgs:_*)
      })
    }
}

Now all the bits are in place, you can create a container by mixing in bindings into the dependency injector. You can mix in any number of bindings, however latter bindings will override any previously registered classes if found. I have been told this goes against the spirit of mixins, which I kind of agree with, but I think it's still a nice way of doing the bindings.

So using the BoundElements trait you could create your container like:

object MyContainer extends DependencyInjector with BoundElements

And you would use it like

MyContainer.get[ClassA]
MyContainer.get[ClassB](new Date(), new InstanceC())

I am also using it to hold traits where I have used the cake pattern.  However this assumes the cake layers don't require any additional variable wiring, or if they do, it will be on a singleton instance.

trait BindCake extends Bindings {
  bind(new DefaultService with DefaultSecurity with DefaultLogging)
}

MyCakeContainer.get[Service]

It would be nice for it to be able to assemble the cake objects itself, but the only way I have seen that might be possible is using twitters eval. I'm open to any ideas.
Also, please feel free to suggest any better ways of handling the mutability of the bindings.

Another thing to note is that the container instance will only exist in the class library with created it, not, say a core library which holds the primary traits and is shared amongst all other libraries.

Edit:
I have found cases where an a get might not work if there isn't a clear inheritance line.  For example, if I registered say Map("value1" -> 123, "value2" -> "result"), and I performed a get with Map[String,Any], I would not get the map object returned.  This is where I would need to do a check against something like:
a => classTag[U].runtimeClass.isAssignableFrom(a.getClass)