CQRS sample app

So this summer I really try to update myself and my coding skills. Next on the list is CQRS.

I attended a Greg Young session at NDC in Oslo and really had a feeling, thats the way applications should be developed. Its been a long time since I had that feeling, I have been comfortably developing my apps basically the same way for the last 8 years or so this is not only refreshing but also a lot of fun, me being the tech nerd I am…

So for about a month or so I have been trying to get a POC CQRS app up and running. Using nServiceBus and MSMQ as transport.

The whole experience (far from finished) can be read and full source can be downloaded from the CQRS NServiceBus example site

Announcing the NHibernate Generic Repository implementation

Ok, so Entity Framework is NOT good enough yet – I will instead focus on NHibernate.

I have created a codeplex open source project for a generic repository. You (client) work against interfaces (there is a EF4 implementation as well in the download, but I as I said, I will not do anything more on that one – for now that is).

My goal has been to provide a generic repository implementation where you don’t have to write different respoitories against each of tables. It instantiates your domain model classes using the ORM – and saving is managed by a UnitOfWork implementation.

Heck, since we are all coders, why not look at some code examples instead:

Here we create a UnitOfWork, we create the repository through the UnitOfWork – a repository against the class Order.Domain.Product. Then we call GetAll to execute the query and get the enumeration.


            //Fetct all products - print every 100
            using (Systementor.Database.Repositories.IUnitOfWork uow = cont2.CreateUnitOfWork(false))
            {

                int n = 0;
                Systementor.Database.Repositories.IRepository<order.Domain.Product> rep = uow.CreateRepository<order.Domain.Product>();
                foreach (Order.Domain.Product p in rep.GetAll())
                {
                    string s = p.Name;
                    if (n == 0)
                        Console.WriteLine(s);
                    n++;
                    if ( n == 100 )
                        n = 0;

                }
            }

Second example, while I am allowing LINQ expressions as specifiers (“where”) – a much nicer way is to use ISpecifications. Your Service layer could implement certain expressions which is then being used as query modifiers:


                Systementor.Database.Repositories.IRepository<order.Domain.Order> rep = uow.CreateRepository<global::Order.Domain.Order>();
                foreach (Order.Domain.Order p in rep.Find(  Service.Specifications.Order.Spec_OrdersContainingProduct(1)  ))
                {
                    string s = p.Id.ToString();
                    Console.WriteLine(s + " contains product");

                }

...
...
SPECIFICATION IS IMPLEMENTED LIKE
        public static Systementor.LinqHelper.Specification.ISpecification<global::Order.Domain.Order> Spec_OrdersContainingProduct(int product_id)
        {
            int prodid = product_id;
            return new Systementor.LinqHelper.Specification.Specification<global::Order.Domain.Order>(p => p.OrderRows.Any(r => r.ProductID == prodid));
        }

Insert/update/delete is also supported of course. Now, just download from

http://systementordatabase.codeplex.com/

EF4 or NHibernate – I’ve made my choice

Ok. So I’ve really given it a fair try. I’ve been to different sessions and courses on EF4 really wanting to give it a chance. However, now when I really had to put it to use in a project I just hit the wall…

I dont know, while Entity Framework 4 sure has it positive sides -  such as great linq support, nice designer – there a lot of things missing. I encountered such as case where I needed a pretty simple query (note – query, not a view, not a SP)  to build up my entity.  I soon realized I had to turn into manually editing the EDMX file for that. It should be possible, but considering you need to do changes to the SSDL, the CSDL AND the mapping part of the file – all referencing each others types – with long namespaces etc – and I wanted to create a one to many relationshoip as well, I simply couldn’t get it working.

Look here for the “manual” http://msdn.microsoft.com/en-us/library/cc982038.aspx

And in NHibernate I did it like:

<class name="ShippingDevliery"  >

    <id name="ShipDate" column="ShipDate" >

      <generator class="assigned" />

    </id>

    <property name="OrdersCount" />

    <set name="Orders" cascade="all" lazy="true">

      <key column="ShipDate" />

      <one-to-many  class="Order" />

    </set>

  </class>

  <sql-query name="loadShippingDevliery">

    <return alias="p" class="ShippingDevliery" />

    <![CDATA[

      select shipdate, count(*) as OrdersCount from Purchasing.PurchaseOrderHeader where shipdate>:shipdate group by shipdate order by shipdate

    ]]>

  </sql-query>

IMO, all in all MS made it way to complicated. You define the model, the conceptual classes (your domain classes) and the mappings in different sections interlinking witth each other where in NHibernate basically you just concentrate in the mappings.

Which is the most important part here to talk about! To be fair, what matters most is the conceptual model. The persistance framework MUST be flexible enough to bend itself to support that. EF4 is so much database first – and for smaller projects where you end up using simple one to one mapping against your domain entities and your database tables.

Maybe, maybe, maybe Code First will change that, but come on, its only a CTP right now.

Seriously, an ORM is supposed to make things easier…And it need to extensible to help us (developers) overcome the shortcomings.

I also hear a lot of fuzz about change tracking. Self tracking entities. While it sounds good, its also the kind of thing you should watch really out for. I mean sending whole entities over the wire back and forth instead of mapping to screen based DTOs so much puts your application into a “CRUD” type of.application. Which also might be fine for some, but putting the extra burden in your client (or mid tier) to make it command based I think will be benefitial in the long run.

oOrder.Save()

compared to

oOrder.ModifyShippingDate(…)
oOrder.InsertNewRow(row)
oOrder.Deleterow2)
etc.

Basically the latter will give you a lot of extra value, you can sane the users *intent*, we didn’t just save, we saved because someone modified the order etc.

I might take a look at EF4 later when Code First is released and the battle isn’t over I guess, but for now I put is aside and kleep on focusing on NHibernate.

Entity Framework generic repositories

…and more…

Continuing my EF4 progress series:
 
Part 1

Part 2

here is now my latest version. What’s new in it? Well basically a lot. Starting with the GUI and functionality I have now crud for orders as well as orderrows. And I have added a new entity into my model, namely product. So you basically start off with searching all orders with one or more orderrows containg the product you selected in the combobox:

We also have some ugly order/orderrow editing screens:

In the download you will find the complete VS2010 solution:

And the parts I am at least somewhat proud of are

Generic repositories

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace Systementor.Database.Repositories
{
    public interface IRepository<t> where T : class
    {
        void Insert(T item);
        void Update(T item);
        void Delete(T item);
        T Get(Expression<func<t, bool>> whereclause);
        T Get(Systementor.LinqHelper.Specification.ISpecification<t> spec);
        int Count(Expression<func<t, bool>> whereclause);
        int Count(Systementor.LinqHelper.Specification.ISpecification<t> spec);
        IList<t> GetAll();
        IList<t> GetAll<t2>(Expression<func<t, T2>> orderbyexpr, int nStartAt = -1, int NumToSel = -1);
        IList<t> Find(Systementor.LinqHelper.Specification.ISpecification<t> spec);
        IList<t> Find(Expression<func<t, bool>> whereclause);

        IList<t> Find<t2>(Expression<func<t, bool>> whereclause, Expression<func<t, T2>> orderbyexpr, int nStartAt = -1, int NumToSel = -1);
        IList<t> Find<t2>(Systementor.LinqHelper.Specification.ISpecification<t> spec, Expression<func<t, T2>> orderbyexpr, int nStartAt = -1, int NumToSel = -1);
}

I have also implemented the specification pattern where queries (where part that is) are handled like

                Systementor.Database.Repositories.IRepository<order.Domain.PurchaseOrderHeader> rep = uow.CreateRepository<order.Domain.PurchaseOrderHeader>();
IList<order.Domain.PurchaseOrderHeader> l = rep.Find(Order.Domain.PurchaseOrderHeader.Spec_OrdersContainingProduct(nSelid))

I.e the business layer code Order.Domain.PurchaseOrderHeader – serves the where specifications possible.

ORM abstraction

look in Systementor.Database.Repositories.IDataContext and the like. I will try to plug NHibernate in soon instead of EF4.

UnitOfWork and EF4 tracing

I have wrapped the EFWrapperToolkit tracing (???) and am able to publish single events for each query – instead of two (commandstarting,commandexecuted)

The eventarguments you (caller) get is

    public class EFTracingEventArgs
    {
        public int CommandId;
        public DateTime dtStarted = new DateTime(1900,1,1);
        public DateTime dtFinished = new DateTime(1900, 1, 1);
        public System.Data.IDbCommand Command;
        public enum StatusEnum
        {
            Executing,
            Finished,
            Failed
        }
        public StatusEnum Status;


Download zip file


Be sure to modify the connectionstring in app.config for GUI

Where to go from here? I was gonna add validation, but soon discovered I better go the full way here and do DTOs instead of sending the entities to the client. So I will do that and add (gui) validation to those. But before that I really need to work on the model. I will simply try to go the DDD route here, I know its a lot easier to go the other way around, here I sit with an existing database – anemic model/no domain expert to tell me, but I’ll fake some requirements and do my best.

My guess is that will render some new Entity Framework 4 problems – I mean I do like having my POCOS autogenerated to start with, but FixupCollection/public setters etc, while extremly convinient, should actually be a no/no in any sane OO aproach, DDD or not.