Lokad.CQRS - Framework that is Designed for Farewells
In Lokad.CQRS documentation there is a recurring pattern. First, we say how to do something in simple and coupled way (i.e.: inherit command handlers from the Define. interfaces). Second, we explain that coupling your domain code to Lokad.CQRS is not the recommended approach for long-term projects. Then, we explain how to decouple your code from the framework (i.e.: by defining your own interfaces and binding to them in the configuration code).
This is actually the approach that I'm trying to apply for the entire Lokad.CQRS. Lokad.CQRS is not "the silver-bullet framework/platform", and it's never going to be. Think of it just like a temporary scaffolding that you can rely on (we certainly do), till you need to switch to something more specific and tailored better to your needs.
As such, this scaffolding should make it easy for you to replace some of the default elements with custom components and even technologies. Ideally, it should even provide clear migration paths both into .NET and out of .NET, if needed.
For example, I'm thinking of the scenario, where I might want to eventually throw away Web-UIs that I've written (they tend to be ugly for some reason) and have them reimplemented by design shops specializing in HTML/CSS. However, since php shops tend to be cheaper and more available than .NET shops (especially in Russia), we might want to stick with them. Luckily, message decoupling and Decide-Act-Report model allow us to do this. We just need to:
- Hand down command and view contracts (and optionally figure out collaboration process if web designers want to change read models).
- Make sure that the web framework tech is capable of communicating with the rest of Lokad.CQRS solution.
To a certain extent this is already possible in Lokad.CQRS, since you can easily specify your own serialization formats for all persistence and messaging. However, at the moment, most elements are still coupled to Windows Azure (you can run portable core locally without any dependencies, but there will be neither persistent queues nor proper endpoints).
Or, consider another approach. We might want to try switching certain elements of our server-side from .NET for something slightly more efficient and cross-platform (future of Mono troubles me at the moment). For instance, think of Scala/Erlang/Akka.
And, you never know, you might eventually find yourself completely outside of .NET stack with no Lokad.CQRS code (except maybe for the maintenance console used to monitor and debug everything).
Again, these are not the things that require major rewrite and thousands of lines of code. They fall nicely into the core concepts behind the framework as long as the core design principles are enforced and followed. These principles are not something new either - just the good old basics of building decoupled systems, messaging, DDD, event architectures and the rest of the gang. However, if you follow them, you will be forced towards creating systems that allow reducing costs of getting locked down in a stack (hence reducing risks) along with handling scalability and design complexity challenges. Lokad.CQRS tries to do it's best to force you to follow them in a rather opinionated way.
I know, designing framework to have a clear migration way out of it, might not seem like a wise choice for consultant-ware. However, Lokad.CQRS is not intended to be source of the revenue anyway. It is just the scaffolding for on-demand forecasting services provided by Lokad. As such, it should help us to manage our risks and provide a clear way to say farewell to technoligies or stacks, if the need arises and is justified financially. This just makes it easier to trust them.
Saturday, June 18, 2011 at 23:01
Reader Comments (2)
Hello, Rinat! What about to use Thrift for your service(command handlers and denormolizer) endpoints, I suppouse it can help you to move toward platform independence?
Mikhail, That could be a valid option for an extension on top of Lokad.CQRS.
Although I'm personally currently moving in the direction of more simple JSON serialization for cross-platform communications.