The Watering Can of Enterprise Software Development
Pouring out information on enterprise software development in the hopes some seeds will grow.

Implementing CQRS Using MVC

Greg was one of the first bloggers to bring the idea of CQRS (Command Query Responsibility Segregation) into the .Net world, so I think it is safe to say he knows what CQRS is. He recently posted a blog on a how CQRS is essentially the same as the MVC UI pattern. He makes this comparison based on the fact that one would use a "command model" and a "query model" in an application. 

 

However, I completely disagree with his relation between a code-based implementation pattern and a data store location. The thing I don’t like about Greg's comparison is that I don't have to use CQRS in MVC and I don't have to implement CQRS using MVC, so I think his statement is going to cause confusion. Therefore saying they are sort of the same doesn’t work for me. Furthermore, I still hold the CQRS is nothing more but a new term to talk about caching.

 

The controller is responsible for separating the view and the model. To that end, one "could" use the controller in an MVC implementation to know which model to read from and which model to write to, although there is no reason you couldn’t have more than two models. The controller would more then likely expose a CQS-style interface and it would probably be a great way to implement CQRS.

 

If I did implement CQRS using MVC then I would probably use a cached abstraction over my model that would look something like this:

 

public class DataStruct {
    public int key { get; set; }
    public string stuff { get; set; }
}

public interface IModel {
    DataStruct GetData(int key);
    void UpdateData(DataStruct data);
    void InsertData(DataStruct data);
}

public class CachedModel : IModel
{
    private readonly Cache _cache = HttpContext.Current.Cache;
    private readonly IModel _model;

    public CachedModel(IModel model) {
        this._model = model;
    }
    public DataStruct GetData(int key) {
        return this._cache.Get(GetKey(key)) as DataStruct ?? GetDataFromStore(key);
    }
    private DataStruct GetDataFromStore(int key) {
        DataStruct data = this._model.GetData(key);
        this._cache.Add(GetKey(key), data, null, DateTime.Now.AddSeconds(30),
            TimeSpan.Zero, CacheItemPriority.Default, null);
        return data;
    }
    public void UpdateData(DataStruct data) {
        this._model.UpdateData(data);
        this._cache.Remove(GetKey(data.key));
    }
    public void InsertData(DataStruct data) {
        this._model.InsertData(data);
    }
    private string GetKey(int key) {
        return string.Format("dataKey:{0}", key);
    }
}

public class Model : IModel {
    private readonly ModelEntities _context;

    public Model(ModelEntities context) {
        this._context = context;
    }
    public DataStruct GetData(int key) {
        return this._context.DataStructs.FirstOrDefault(d => d.key == key);
    }
    public void InsertData(DataStruct data) {
        this._context.AddToDataStructs(data);

 

   

Tags: .Net| CQRS| MVC
Labels: development
Search
Follow Us