Skip to content

Instantly share code, notes, and snippets.

@philcleveland
Last active January 7, 2016 06:24
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save philcleveland/4658759 to your computer and use it in GitHub Desktop.
Save philcleveland/4658759 to your computer and use it in GitHub Desktop.
public abstract class AggregateRoot : IAggregateRoot
{
private const int DefaultVersion = 0;
private readonly Dictionary<Type, Action<IEvent>> handlers = new Dictionary<Type, Action<IEvent>>();
private List<IEvent> _uncommitedChanges = new List<IEvent>();
public Guid Id { get; protected set; }
public int Version { get; private set; }
public AggregateRoot()
{
Version = DefaultVersion;
}
public void Apply(IEvent @event)
{
if(@event.Version == Event.DefaultVersion)
_uncommitedChanges.Add(@event);
@event.Version = this.Version + 1;
this.handlers[@event.GetType()].Invoke(@event);
++Version;
}
public void Apply(IEnumerable<IEvent> @events)
{
foreach (var @event in @events)
{
Apply(@event);
}
}
public List<IEvent> GetUncommitedChanges()
{
return _uncommitedChanges;
}
public void ClearUncommitedChanges()
{
_uncommitedChanges.Clear();
}
protected void Handles<TEvent>(Action<TEvent> handler)
where TEvent : IEvent
{
this.handlers.Add(typeof(TEvent), @event => handler((TEvent)@event));
}
}
public abstract class Event : IEvent
{
public const int DefaultVersion = -1;
private Guid _eventId = Guid.NewGuid();
private DateTime _eventTimestamp = DateTime.Now.ToUniversalTime();
private int _version = DefaultVersion;
public Guid EventId
{
get { return _eventId; }
}
public DateTime EventTimestamp
{
get { return _eventTimestamp; }
}
public int Version
{
get { return _version; }
set { _version = value; }
}
// override object.Equals
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
return Equals((Event)obj);
}
public bool Equals(Event other)
{
return EventId.Equals(other.EventId);
}
public override int GetHashCode()
{
return EventId.GetHashCode();
}
public override string ToString()
{
return String.Format("{0}: ", EventTimestamp.ToString("MM/dd/yyyy hh:mm:ss.fff tt"));
}
}
public interface IAggregateRoot
{
Guid Id { get; }
int Version { get; }
void Apply(IEvent @event);
void Apply(IEnumerable<IEvent> events);
void ClearUncommitedChanges();
List<IEvent> GetUncommitedChanges();
}
public interface IEvent
{
Guid EventId { get; }
DateTime EventTimestamp { get; }
int Version { get; set; }
}
public interface IRepository
{
TAggregate GetById<TAggregate>(Guid id) where TAggregate : class, IAggregateRoot;
TAggregate GetById<TAggregate>(Guid id, int version) where TAggregate : class, IAggregateRoot;
void Save(IAggregateRoot aggregate, Guid commitId, Action<IDictionary<string, object>> updateHeaders);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment