Line data Source code
1 : #region Copyright
2 : // // -----------------------------------------------------------------------
3 : // // <copyright company="cdmdotnet Limited">
4 : // // Copyright cdmdotnet Limited. All rights reserved.
5 : // // </copyright>
6 : // // -----------------------------------------------------------------------
7 : #endregion
8 :
9 : using System;
10 : using System.Collections.Generic;
11 : using System.Collections.ObjectModel;
12 : using System.Linq;
13 : using System.Threading;
14 : using Cqrs.Domain.Exceptions;
15 : using Cqrs.Events;
16 : using Cqrs.Infrastructure;
17 :
18 : namespace Cqrs.Domain
19 : {
20 : public abstract class AggregateRoot<TAuthenticationToken> : IAggregateRoot<TAuthenticationToken>
21 0 : {
22 : private ReaderWriterLockSlim Lock { get; set; }
23 :
24 : private ICollection<IEvent<TAuthenticationToken>> Changes { get; set; }
25 :
26 : public Guid Id { get; protected set; }
27 :
28 : public int Version { get; protected set; }
29 :
30 0 : protected AggregateRoot()
31 : {
32 : Lock = new ReaderWriterLockSlim();
33 : Changes = new ReadOnlyCollection<IEvent<TAuthenticationToken>>(new List<IEvent<TAuthenticationToken>>());
34 : }
35 :
36 0 : public IEnumerable<IEvent<TAuthenticationToken>> GetUncommittedChanges()
37 : {
38 : return Changes;
39 : }
40 :
41 0 : public virtual void MarkChangesAsCommitted()
42 : {
43 : Lock.EnterWriteLock();
44 : try
45 : {
46 : Version = Version + Changes.Count;
47 : Changes = new ReadOnlyCollection<IEvent<TAuthenticationToken>>(new List<IEvent<TAuthenticationToken>>());
48 : }
49 : finally
50 : {
51 : Lock.ExitWriteLock();
52 : }
53 : }
54 :
55 0 : public virtual void LoadFromHistory(IEnumerable<IEvent<TAuthenticationToken>> history)
56 : {
57 : Type aggregateType = GetType();
58 : foreach (IEvent<TAuthenticationToken> @event in history.OrderBy(e => e.Version))
59 : {
60 : if (@event.Version != Version + 1)
61 : throw new EventsOutOfOrderException(@event.Id, aggregateType, Version + 1, @event.Version);
62 : ApplyChange(@event, true);
63 : }
64 : }
65 :
66 0 : protected virtual void ApplyChange(IEvent<TAuthenticationToken> @event)
67 : {
68 : ApplyChange(@event, false);
69 : }
70 :
71 : private void ApplyChange(IEvent<TAuthenticationToken> @event, bool isEventReplay)
72 : {
73 : Lock.EnterWriteLock();
74 : try
75 : {
76 : this.AsDynamic().Apply(@event);
77 : if (!isEventReplay)
78 : {
79 : Changes = new ReadOnlyCollection<IEvent<TAuthenticationToken>>(new []{@event}.Concat(Changes).ToList());
80 : }
81 : else
82 : {
83 : Id = @event.Id;
84 : Version++;
85 : }
86 : }
87 : finally
88 : {
89 : Lock.ExitWriteLock();
90 : }
91 : }
92 : }
93 : }
|