Skip to content

Instantly share code, notes, and snippets.

@Pondidum
Created November 10, 2016 12:10
Show Gist options
  • Select an option

  • Save Pondidum/c83150c027be8a27c5e750ec2189f540 to your computer and use it in GitHub Desktop.

Select an option

Save Pondidum/c83150c027be8a27c5e750ec2189f540 to your computer and use it in GitHub Desktop.
public class AggregateController
{
private readonly List<object> _uncommittedEvents;
private readonly Dictionary<Type, Action<object>> _handlers;
public AggregateController(object aggregate)
{
_uncommittedEvents = new List<object>();
_handlers =aggregate
.GetType()
.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
.Where(method => method.Name == "Handle" || method.Name == "Handles")
.Where(method => method.GetParameters().Length == 1)
.ToDictionary(
method => method.GetParameters().Single().ParameterType,
method => new Action<object>(val => method.Invoke(aggregate, new[] { val }))
);
}
public IEnumerable<object> GetUncommittedEvents()
{
return _uncommittedEvents;
}
internal void MarkEventsCommitted()
{
_uncommittedEvents.Clear();
}
public void ApplyEvent(object @event)
{
HandleEvent(@event);
_uncommittedEvents.Add(@event);
}
private void HandleEvent(object domainEvent)
{
Action<object> handler;
if (_handlers.TryGetValue(domainEvent.GetType(), out handler) == false)
throw new MissingMethodException(GetType().Name, $"Handles({domainEvent.GetType().Name} e)");
handler(domainEvent);
}
}
public class Quest
{
public Guid Id { get; protected set; }
public string Name { get; private set; }
public int CurrentDay { get; private set; }
public string CurrentLocation { get; private set; }
public IEnumerable<string> Members => _members;
private readonly HashSet<string> _members;
private readonly AggregateController _controller;
private Quest()
{
_members = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
_controller = new AggregateController(this);
}
public static Quest StartNew(string name)
{
var quest = new Quest();
quest._controller.ApplyEvent(new QuestStarted { Id = Guid.NewGuid(), Name = name });
return quest;
}
public void AddMembers(int day, string location, params string[] members)
{
_controller.ApplyEvent(new MembersJoined(day, location, members));
}
private void Handles(QuestStarted e)
{
Id = e.Id;
Name = e.Name;
CurrentDay = 1;
CurrentLocation = string.Empty;
}
private void Handles(MembersJoined e)
{
CurrentDay = e.Day;
CurrentLocation = e.Location;
foreach (var member in e.Members)
_members.Add(member);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment