Skip to content

Commit

Permalink
Exposed the EventRouter from AggregateBase, so that we don't have to …
Browse files Browse the repository at this point in the history
…call the default constructor when instantiating aggregates. Made throwing exceptions when apply methods arenot found optional, so that historical events don't have to have empty apply methods.
  • Loading branch information
kblooie committed Dec 1, 2011
1 parent 28713da commit 49fe176
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 66 deletions.
147 changes: 83 additions & 64 deletions src/proj/CommonDomain.Core/AggregateBase.cs
Original file line number Diff line number Diff line change
@@ -1,74 +1,93 @@
namespace CommonDomain.Core
{
using System;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Collections;
using System.Collections.Generic;

public abstract class AggregateBase : IAggregate, IEquatable<IAggregate>
{
private readonly ICollection<object> uncommittedEvents = new LinkedList<object>();
private readonly IRouteEvents registeredRoutes = new ConventionEventRouter();
public abstract class AggregateBase : IAggregate, IEquatable<IAggregate>
{
private readonly ICollection<object> uncommittedEvents = new LinkedList<object>();

protected AggregateBase()
: this(null)
{
}
protected AggregateBase(IRouteEvents handler)
{
this.registeredRoutes = handler ?? this.registeredRoutes;
this.registeredRoutes.Register(this);
}
private IRouteEvents registeredRoutes;

public Guid Id { get; protected set; }
public int Version { get; protected set; }
protected AggregateBase()
: this(null)
{
}

protected void Register<T>(Action<T> route)
{
this.registeredRoutes.Register(route);
}
protected AggregateBase(IRouteEvents handler)
{
if (handler == null) return;

protected void RaiseEvent(object @event)
{
((IAggregate)this).ApplyEvent(@event);
this.uncommittedEvents.Add(@event);
}
void IAggregate.ApplyEvent(object @event)
{
this.registeredRoutes.Dispatch(@event);
this.Version++;
}
ICollection IAggregate.GetUncommittedEvents()
{
return (ICollection)this.uncommittedEvents;
}
void IAggregate.ClearUncommittedEvents()
{
this.uncommittedEvents.Clear();
}
this.RegisteredRoutes = handler;
this.RegisteredRoutes.Register(this);
}

IMemento IAggregate.GetSnapshot()
{
var snapshot = this.GetSnapshot();
snapshot.Id = this.Id;
snapshot.Version = this.Version;
return snapshot;
}
protected virtual IMemento GetSnapshot()
{
return null;
}
public Guid Id { get; protected set; }
public int Version { get; protected set; }

public override int GetHashCode()
{
return this.Id.GetHashCode();
}
public override bool Equals(object obj)
{
return this.Equals(obj as IAggregate);
}
public virtual bool Equals(IAggregate other)
{
return null != other && other.Id == this.Id;
}
}
protected IRouteEvents RegisteredRoutes
{
get
{
return registeredRoutes ?? (registeredRoutes = new ConventionEventRouter(true, this));
}
set
{
if (value == null)
throw new InvalidOperationException("AggregateBase must have an event router to function");

registeredRoutes = value;
}
}

protected void Register<T>(Action<T> route)
{
this.registeredRoutes.Register(route);
}

protected void RaiseEvent(object @event)
{
((IAggregate)this).ApplyEvent(@event);
this.uncommittedEvents.Add(@event);
}
void IAggregate.ApplyEvent(object @event)
{
this.registeredRoutes.Dispatch(@event);
this.Version++;
}
ICollection IAggregate.GetUncommittedEvents()
{
return (ICollection)this.uncommittedEvents;
}
void IAggregate.ClearUncommittedEvents()
{
this.uncommittedEvents.Clear();
}

IMemento IAggregate.GetSnapshot()
{
var snapshot = this.GetSnapshot();
snapshot.Id = this.Id;
snapshot.Version = this.Version;
return snapshot;
}
protected virtual IMemento GetSnapshot()
{
return null;
}

public override int GetHashCode()
{
return this.Id.GetHashCode();
}
public override bool Equals(object obj)
{
return this.Equals(obj as IAggregate);
}
public virtual bool Equals(IAggregate other)
{
return null != other && other.Id == this.Id;
}
}
}
19 changes: 17 additions & 2 deletions src/proj/CommonDomain.Core/ConventionEventRouter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,24 @@ namespace CommonDomain.Core

public class ConventionEventRouter : IRouteEvents
{
private readonly IDictionary<Type, Action<object>> handlers = new Dictionary<Type, Action<object>>();
readonly bool throwOnApplyNotFound;
private readonly IDictionary<Type, Action<object>> handlers = new Dictionary<Type, Action<object>>();
private IAggregate registered;

public ConventionEventRouter() : this(true)
{
}

public ConventionEventRouter(bool throwOnApplyNotFound)
{
this.throwOnApplyNotFound = throwOnApplyNotFound;
}

public ConventionEventRouter(bool throwOnApplyNotFound, IAggregate aggregate) : this(throwOnApplyNotFound)
{
Register(aggregate);
}

public virtual void Register<T>(Action<T> handler)
{
if (handler == null)
Expand Down Expand Up @@ -50,7 +65,7 @@ public virtual void Dispatch(object eventMessage)
Action<object> handler;
if (this.handlers.TryGetValue(eventMessage.GetType(), out handler))
handler(eventMessage);
else
else if(this.throwOnApplyNotFound)
this.registered.ThrowHandlerNotFound(eventMessage);
}

Expand Down

0 comments on commit 49fe176

Please sign in to comment.