Skip to content

Instantly share code, notes, and snippets.

@ToJans
Created December 16, 2010 12:01
Show Gist options
  • Save ToJans/743323 to your computer and use it in GitHub Desktop.
Save ToJans/743323 to your computer and use it in GitHub Desktop.
Another CQRS approach, a little verbose, but very safe to use
namespace AnotherInterfaceForCQRS
{
public interface IConsume<TChange>
{
void Consume(TChange change);
}
public interface IRun<THandler,TCommand>
{
void Run(THandler handler,TCommand command);
}
public static class DispatchHelper
{
public static void DispatchChange<TConsumer,TChange>(this TConsumer self,TChange change) where TConsumer:IConsume<TChange>
{
// save the change in a store
self.Consume(change);
// dispatch the change to other handlers
}
}
}
using System;
using AnotherInterfaceForCQRS;
namespace SomeDomain.Contexts.ItemContext
{
public class OrderAnItem
{
public Guid OrderId;
public Guid ProductId;
public int Quantity;
}
public class ItemAdded
{
public Guid OrderId;
public Guid ProductId;
}
public class ItemRemoved
{
public Guid OrderId;
public Guid ProductId;
}
public class ItemQuantityChanged
{
public Guid OrderId;
public Guid ProductId;
public int Quantity;
}
public interface IRunItemCommands<THandler>
:IRun<THandler, OrderAnItem>
{}
public interface IConsumeItemChanges
:IConsume<ItemAdded>
,IConsume<ItemRemoved>
,IConsume<ItemQuantityChanged>
{ }
}
namespace SomeDomain.Contexts.OrderValidationContext
{
public class RequestOrderValidation
{
public Guid OrderId;
public Guid RequesterId;
}
public class OrderValidationRequested
{
public Guid OrderId;
public Guid RequesterId;
}
public class ValidateOrder
{
public Guid OrderId;
public Guid ValidatorId;
}
public class InvalidateOrder
{
public Guid OrderId;
public Guid ValidatorId;
public string Reason;
}
public class OrderValidated
{
public Guid OrderId;
public Guid ValidatorId;
}
public class OrderInvalidated
{
public Guid OrderId;
public Guid ValidatorId;
public string Reason;
}
public interface IRunOrderValidationCommands<THandler>
:IRun<THandler,RequestOrderValidation>
,IRun<THandler,ValidateOrder>
,IRun<THandler,InvalidateOrder>
{}
public interface IConsumeOrderValidationChanges
:IConsume<OrderValidationRequested>
,IConsume<OrderValidated>
,IConsume<OrderInvalidated>
{}
}
using System;
using System.Collections.Generic;
using AnotherInterfaceForCQRS;
using SomeDomain.Contexts.ItemContext;
using SomeDomain.Contexts.OrderValidationContext;
namespace SomeDomain.Implementation
{
public class OrderCommandHandler
:IRunOrderValidationCommands<Order>
,IRunItemCommands<Order>
{
public void Run(Order handler, OrderAnItem command)
{
if (command.Quantity!=0)
handler.OrderAnItem(command.ProductId,command.Quantity);
}
public void Run(Order handler, RequestOrderValidation command)
{
throw new NotImplementedException();
}
public void Run(Order handler, ValidateOrder command)
{
throw new NotImplementedException();
}
public void Run(Order handler, InvalidateOrder command)
{
throw new NotImplementedException();
}
}
public class Order
:IConsumeItemChanges
,IConsumeOrderValidationChanges
{
protected Guid Id;
protected Dictionary<Guid,int> ProductAmounts = new Dictionary<Guid, int>();
public void OrderAnItem(Guid ProductId, int Quantity)
{
if (!ProductAmounts.ContainsKey(ProductId))
this.DispatchChange(new ItemAdded() { OrderId = Id,ProductId = ProductId });
if (ProductAmounts[ProductId]+Quantity == 0)
this.DispatchChange(new ItemRemoved() { OrderId = Id,ProductId = ProductId });
else
this.DispatchChange(new ItemQuantityChanged() { OrderId = Id,ProductId = ProductId,Quantity = Quantity} );
}
void IConsume<ItemAdded>.Consume(ItemAdded change)
{
ProductAmounts.Add(change.ProductId,0);
}
void IConsume<ItemRemoved>.Consume(ItemRemoved change)
{
ProductAmounts.Remove(change.ProductId);
}
void IConsume<ItemQuantityChanged>.Consume(ItemQuantityChanged change)
{
ProductAmounts[change.ProductId] += change.Quantity;
}
void IConsume<OrderValidationRequested>.Consume(OrderValidationRequested change)
{
throw new NotImplementedException();
}
void IConsume<OrderValidated>.Consume(OrderValidated change)
{
throw new NotImplementedException();
}
void IConsume<OrderInvalidated>.Consume(OrderInvalidated change)
{
throw new NotImplementedException();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment