Created
November 10, 2016 12:10
-
-
Save Pondidum/c83150c027be8a27c5e750ec2189f540 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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