Skip to content

Commit c42476b

Browse files
committed
Merge branch 'develop'
2 parents e508a88 + 654766a commit c42476b

File tree

89 files changed

+3662
-2022
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+3662
-2022
lines changed

Documentation/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
_build

Documentation/Aggregates.md

Lines changed: 0 additions & 98 deletions
This file was deleted.

Documentation/Aggregates.rst

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
.. _aggregates:
2+
3+
Aggregates
4+
==========
5+
6+
Initially before you can create a aggregate, you need to create its
7+
identity. You can create your own implementation by implementing the
8+
``IIdentity`` interface or you can use a base class ``Identity<>`` that
9+
EventFlow provides, like this.
10+
11+
.. code-block:: c#
12+
13+
public class TestId : Identity<TestId>
14+
{
15+
public TestId(string value) : base(value)
16+
{
17+
}
18+
}
19+
20+
The :ref:`Identity\<\> <identity>` value object
21+
provides generic functionality to create and validate aggregate root
22+
IDs. Please read the documentation regarding the bundled ``Identity<>``
23+
type as it provides several useful features, e.g. several different
24+
schemes for ID generation, one that minimizes MSSQL database
25+
fragmentation.
26+
27+
Next, to create a new aggregate, simply inherit from
28+
``AggregateRoot<,>`` like this, making sure to pass test aggregate own
29+
type as the first generic argument and the identity as the second.
30+
31+
.. code-block:: c#
32+
33+
public class TestAggregate : AggregateRoot<TestAggregate, TestId>
34+
{
35+
public TestAggregate(TestId id)
36+
: base(id)
37+
{
38+
}
39+
}
40+
41+
Events
42+
------
43+
44+
In an event source system like EventFlow, aggregate root data are stored
45+
on events.
46+
47+
.. code-block:: c#
48+
49+
public class PingEvent : AggregateEvent<TestAggregate, TestId>
50+
{
51+
public string Data { get; }
52+
public PingEvent(string data)
53+
{
54+
Data = data;
55+
}
56+
}
57+
58+
Please make sure to read the section on :ref:`value objects and
59+
events <value-objects>` for some important notes on creating
60+
events.
61+
62+
Emitting events
63+
---------------
64+
65+
In order to emit an event from an aggregate, call the ``protected``
66+
``Emit(...)`` method which applies the event and adds it to the list of
67+
uncommitted events.
68+
69+
.. code-block:: c#
70+
71+
public void Ping(string data)
72+
{
73+
// Fancy domain logic here that validates aggregate state...
74+
75+
if (string.IsNullOrEmpty(data))
76+
{
77+
throw DomainError.With("Ping data empty")
78+
}
79+
80+
Emit(new PingEvent(data))
81+
}
82+
83+
Remember not to do any changes to the aggregate with the these methods,
84+
as as state are only stored through events and how they are applied to
85+
the aggregate root.
86+
87+
Applying events
88+
---------------
89+
90+
Currently EventFlow has three methods of applying events to the
91+
aggregate when emitted or loaded from the event store. Which you choose
92+
is up to you, implementing ``IEmit<SomeEvent>`` is the most convenient,
93+
but will expose public ``Apply`` methods.
94+
95+
- Create a method called ``Apply`` that takes the event as argument. To
96+
get the method signature right, implement the ``IEmit<SomeEvent>`` on
97+
your aggregate. This is the default fallback and you will get an
98+
exception if no other strategies are configured. Although you *can*
99+
implement ``IEmit<SomeEvent>``, its optional, the ``Apply`` methods
100+
can be ``protected`` or ``private``
101+
- Create a state object by inheriting from ``AggregateState<,,>`` and
102+
registering using the protected ``Register(...)`` in the aggregate
103+
root constructor
104+
- Register a specific handler for a event using the protected
105+
``Register<SomeEvent>(e => Handler(e))`` from within the constructor
106+
- Register an event applier using
107+
``Register(IEventApplier eventApplier)``, which could be a e.g state
108+
object

Documentation/Commands.md

Lines changed: 0 additions & 147 deletions
This file was deleted.

0 commit comments

Comments
 (0)