<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>Elegant Code</title>
	
	<link>http://elegantcode.com</link>
	<description />
	<lastBuildDate>Sat, 21 Nov 2009 01:18:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/ElegantCode" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>CQRS – The Domain Events</title>
		<link>http://elegantcode.com/2009/11/20/cqrs-the-domain-events/</link>
		<comments>http://elegantcode.com/2009/11/20/cqrs-the-domain-events/#comments</comments>
		<pubDate>Sat, 21 Nov 2009 01:17:39 +0000</pubDate>
		<dc:creator>Mark Nijhof</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[CQRS]]></category>
		<category><![CDATA[DDD]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/11/20/cqrs-the-domain-events/</guid>
		<description><![CDATA[As you may have seen in my previous post “CQRS à la Greg Young” now our domain aggregate root is responsible for publishing domain events indicating that some internal state has changed. In fact state changes within our aggregate root are _only_ allowed through such domain events. Secondly the internal event handlers are _not_ allowed [...]]]></description>
			<content:encoded><![CDATA[<p>As you may have seen in my previous post “<a href="http://elegantcode.com/2009/11/11/cqrs-la-greg-young/" target="_blank">CQRS à la Greg Young</a>” now our domain aggregate root is responsible for publishing domain events indicating that some internal state has changed. In fact state changes within our aggregate root are _only_ allowed through such domain events. Secondly the internal event handlers are _not_ allowed to have any sort of business logic in them, they are _only_ supposed to set or update the internal state of the aggregate root directly from the data the event carries. Using these rules you completely separate the business logic from the state changes. This separation enables us to replay historical domain events without any business logic being triggered bringing it back to the same state as the original aggregate root.</p>
<p>Why is this important? Well now we can use these same domain events for our persistence using an Event Store, this pattern by Martin Fowler is called “<a href="http://martinfowler.com/eaaDev/EventSourcing.html" target="_blank">Event Sourcing</a>”. Obviously you don’t want to process a credit card or send an e-mail every time you load an aggregate root from the event store. Also from the time the original domain event was recorded and when the aggregate root is loaded from the event store the business logic that decided a state change was needed could have changed, this should not affect the actual historical state change. So this separation is to be taken seriously.</p>
<p>Domain events can also be used to signal something to the outside world (taken from the aggregate roots view point) that something has happened without having an actual state change. When persisting our domain events we would not differentiate between those two different domain events. </p>
<p>All domain events should be named with the ubiquitous language in mind, meaning that they should closely represent what the user intended to do in the same language as the user would use to explain it to you. By keeping all these domain events we gain a huge amount of knowledge about what happened and why it happened.</p>
<p>This means that our aggregate root gets the added responsibility of tracking these domain events, but I don’t see this as being any different then for example the proxy that NHibernate generates for you, except perhaps that it is not a proxy and that you have more control over what happens. But it is true your aggregate root has these added responsibilities.</p>
<p>So let us take a look at how the aggregate root provides this functionality, for obvious reasons we use a base class for this, but really all that is needed is that the aggregate root implements the following two interfaces:</p>
<div style="padding-bottom: 10px; margin: 0px; font-family: monaco,verdana; background: rgb(22,36,51); color: white; font-size: 10pt; overflow: scroll; padding-top: 10px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 1</span>&#160;<span style="color: #0080c0">namespace</span> Fohjin<span style="color: aqua">.</span>DDD<span style="color: aqua">.</span>EventStore<span style="color: aqua">.</span>Storage<span style="color: aqua">.</span>Memento</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 2</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 3</span>&#160;&#160;&#160;&#160; <span style="color: #0080c0">public</span> <span style="color: #0080c0">interface</span> <span style="color: #2b91af">IOrginator</span></pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 4</span>&#160;&#160;&#160;&#160; {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 5</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">IMemento</span> CreateMemento();</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 6</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0080c0">void</span> SetMemento(<span style="color: #2b91af">IMemento</span> memento);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 7</span>&#160;&#160;&#160;&#160; }</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 8</span> }</pre>
</div>
<p></p>
<p>The IOrginator interface is for the snapshot functionality which is an optimization technique for speeding up loading aggregate roots from the Event Store. As you can see it is using the “Memento” patter from the <a href="http://c2.com/cgi/wiki?GangOfFour" target="_blank">Gang Of Four</a> book. I wanted to get this interface out of the way first; it is not needed, but does provide a good optimization for loading aggregate roots.</p>
<div style="padding-bottom: 10px; margin: 0px; font-family: monaco,verdana; background: rgb(22,36,51); color: white; font-size: 10pt; overflow: scroll; padding-top: 10px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 1</span>&#160;<span style="color: #0080c0">namespace</span> Fohjin<span style="color: aqua">.</span>DDD<span style="color: aqua">.</span>EventStore</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 2</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 3</span>&#160;&#160;&#160;&#160; <span style="color: #0080c0">public</span> <span style="color: #0080c0">interface</span> <span style="color: #2b91af">IEventProvider</span></pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 4</span>&#160;&#160;&#160;&#160; {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 5</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0080c0">void</span> Clear();</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 6</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0080c0">void</span> LoadFromHistory(<span style="color: #2b91af">IEnumerable</span><span style="color: aqua">&lt;</span><span style="color: #2b91af">IDomainEvent</span><span style="color: aqua">&gt;</span> domainEvents);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 7</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0080c0">void</span> UpdateVersion(<span style="color: #0080c0">int</span> version);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 8</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">Guid</span> Id { <span style="color: #0080c0">get</span>; }</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 9</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0080c0">int</span> Version { <span style="color: #0080c0">get</span>; }</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 10</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">IEnumerable</span><span style="color: aqua">&lt;</span><span style="color: #2b91af">IDomainEvent</span><span style="color: aqua">&gt;</span> GetChanges();</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 11</span>&#160;&#160;&#160;&#160; }</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 12</span> }</pre>
</div>
<p></p>
<p>The IEventProvider interface is the most interesting interface of the two, this one defines how domain events can be retrieved from the aggregate root and how historical domain events can be loaded back. It also defines that each aggregate root must have an Id and a Version, both of these are used by the event store, the Id is obvious so I won’t go into that, the version on the other hand may not be that obvious. The version is used to detect concurrency violations, meaning this is used to prevent conflicts that occur because between the time the command was send and the aggregate root was saved an other user or process has updated the same aggregate root. In this case we would throw an Concurrency Violation Exception which currently results in a rollback. In a future post I plan to look into how you could try to deal with these concurrency violations automatically.</p>
<h2>Using domain events for state change</h2>
<p>Now we will take a look at how these interfaces are implemented and how the implementation is used. The way I am going to go through the code is as if you where using R# going from method to method. So in order to get a more overall impression&#160; I would encourage you to look at the source code. The source code can be found here: <a href="http://github.com/MarkNijhof/Fohjin">http://github.com/MarkNijhof/Fohjin</a></p>
<p>Each aggregate root has to register the domain events and the internal event handlers with the base class. I am working on getting this as static information for the type since this will not change between different instances of the same type. As you can see I am registering the domain event type and an action to handle the specific type. As you can see the actions have the specific domain event as an input parameter.</p>
<div style="padding-bottom: 10px; margin: 0px; font-family: monaco,verdana; background: rgb(22,36,51); color: white; font-size: 10pt; overflow: scroll; padding-top: 10px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 1</span>&#160;<span style="color: #0080c0">private</span> <span style="color: #0080c0">void</span> registerEvents()</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 2</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 3</span>&#160;&#160;&#160;&#160; RegisterEvent<span style="color: aqua">&lt;</span><span style="color: #2b91af">ClientCreatedEvent</span><span style="color: aqua">&gt;</span>(onNewClientCreated);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 4</span>&#160;&#160;&#160;&#160; RegisterEvent<span style="color: aqua">&lt;</span><span style="color: #2b91af">ClientMovedEvent</span><span style="color: aqua">&gt;</span>(onNewClientMoved);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 5</span> }</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 6</span>&#160;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 7</span>&#160;<span style="color: #0080c0">private</span> <span style="color: #0080c0">void</span> onNewClientCreated(<span style="color: #2b91af">ClientCreatedEvent</span> clientCreatedEvent)</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 8</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 9</span>&#160;&#160;&#160;&#160; Id <span style="color: aqua">=</span> clientCreatedEvent<span style="color: aqua">.</span>ClientId;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 10</span>&#160;&#160;&#160;&#160; _clientName <span style="color: aqua">=</span> <span style="color: #0080c0">new</span> <span style="color: #2b91af">ClientName</span>(clientCreatedEvent<span style="color: aqua">.</span>ClientName);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 11</span>&#160;&#160;&#160;&#160; _address <span style="color: aqua">=</span> <span style="color: #0080c0">new</span> <span style="color: #2b91af">Address</span>(clientCreatedEvent<span style="color: aqua">.</span>Street, clientCreatedEvent<span style="color: aqua">.</span>StreetNumber, clientCreatedEvent<span style="color: aqua">.</span>PostalCode, clientCreatedEvent<span style="color: aqua">.</span>City);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 12</span>&#160;&#160;&#160;&#160; _phoneNumber <span style="color: aqua">=</span> <span style="color: #0080c0">new</span> <span style="color: #2b91af">PhoneNumber</span>(clientCreatedEvent<span style="color: aqua">.</span>PhoneNumber);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 13</span> }</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 14</span>&#160;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 15</span>&#160;<span style="color: #0080c0">private</span> <span style="color: #0080c0">void</span> onNewClientMoved(<span style="color: #2b91af">ClientMovedEvent</span> clientMovedEvent)</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 16</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 17</span>&#160;&#160;&#160;&#160; _address <span style="color: aqua">=</span> <span style="color: #0080c0">new</span> <span style="color: #2b91af">Address</span>(clientMovedEvent<span style="color: aqua">.</span>Street, clientMovedEvent<span style="color: aqua">.</span>StreetNumber, clientMovedEvent<span style="color: aqua">.</span>PostalCode, clientMovedEvent<span style="color: aqua">.</span>City);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 18</span> }</pre>
</div>
<p></p>
<p>The RegisterEvent method is defined in the BaseAggregateRoot class, here is a little bit of interesting logic going on where basically a new action is defined that has an IDomainEvent as an input parameter, that is how they can all be stored in the same Dictionary. Then inside this action the provided action is invoked where the input value is cast from an IDomainEvent to the actual expected type TEvent.</p>
<div style="padding-bottom: 10px; margin: 0px; font-family: monaco,verdana; background: rgb(22,36,51); color: white; font-size: 10pt; overflow: scroll; padding-top: 10px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 1</span>&#160;<span style="color: #0080c0">private</span> <span style="color: #0080c0">readonly</span> <span style="color: #2b91af">Dictionary</span><span style="color: aqua">&lt;</span><span style="color: #2b91af">Type</span>, <span style="color: #2b91af">Action</span><span style="color: aqua">&lt;</span><span style="color: #2b91af">IDomainEvent</span><span style="color: aqua">&gt;&gt;</span> _registeredEvents;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 2</span>&#160;<span style="color: #0080c0">protected</span> <span style="color: #0080c0">void</span> RegisterEvent<span style="color: aqua">&lt;</span>TEvent<span style="color: aqua">&gt;</span>(<span style="color: #2b91af">Action</span><span style="color: aqua">&lt;</span>TEvent<span style="color: aqua">&gt;</span> eventHandler) <span style="color: #0080c0">where</span> TEvent : <span style="color: #0080c0">class</span>, <span style="color: #2b91af">IDomainEvent</span></pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 3</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 4</span>&#160;&#160;&#160;&#160; _registeredEvents<span style="color: aqua">.</span>Add(<span style="color: #0080c0">typeof</span>(TEvent), theEvent <span style="color: aqua">=&gt;</span> eventHandler(theEvent <span style="color: #0080c0">as</span> TEvent));</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 5</span> }</pre>
</div>
<p></p>
<p>So if we would write the example out of what is actually happening for the Client Created Event then it would look like this example below, and this is what is being stored in the _registeredEvents.</p>
<div style="padding-bottom: 10px; margin: 0px; font-family: monaco,verdana; background: rgb(22,36,51); color: white; font-size: 10pt; overflow: scroll; padding-top: 10px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 1</span>&#160;<span style="color: #0080c0">public</span> <span style="color: #0080c0">void</span> Delegate(<span style="color: #2b91af">IDomainEvent</span> domainEvent)</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 2</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 3</span>&#160;&#160;&#160;&#160; onNewClientCreated(domainEvent <span style="color: #0080c0">as</span> <span style="color: #2b91af">ClientCreatedEvent</span>);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 4</span> }</pre>
</div>
<p></p>
<p>And below here is the private apply method that is being called from two different methods in the aggregate root base class. The method retrieves the action that is registered for the provided domain event, and than it invokes the action with the domain event as the input parameter. The apply method takes an IDomainEvent instead of the specific domain event and because of that we have the above mentioned logic.</p>
<div style="padding-bottom: 10px; margin: 0px; font-family: monaco,verdana; background: rgb(22,36,51); color: white; font-size: 10pt; overflow: scroll; padding-top: 10px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 1</span>&#160;<span style="color: #0080c0">private</span> <span style="color: #0080c0">void</span> apply(<span style="color: #2b91af">Type</span> eventType, <span style="color: #2b91af">IDomainEvent</span> domainEvent)</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 2</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 3</span>&#160;&#160;&#160;&#160; <span style="color: #2b91af">Action</span><span style="color: aqua">&lt;</span><span style="color: #2b91af">IDomainEvent</span><span style="color: aqua">&gt;</span> handler;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 4</span>&#160;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 5</span>&#160;&#160;&#160;&#160; <span style="color: #0080c0">if</span> (<span style="color: aqua">!</span>_registeredEvents<span style="color: aqua">.</span>TryGetValue(eventType, <span style="color: #0080c0">out</span> handler))</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 6</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0080c0">throw</span> <span style="color: #0080c0">new</span> <span style="color: #2b91af">UnregisteredDomainEventException</span>(<span style="color: #0080c0">string</span><span style="color: aqua">.</span>Format(<span style="color: #a31515">&quot;The requested domain event '{0}' is not registered in '{1}'&quot;</span>, eventType<span style="color: aqua">.</span>FullName, GetType()<span style="color: aqua">.</span>FullName));</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 7</span>&#160;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 8</span>&#160;&#160;&#160;&#160; handler(domainEvent);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 9</span> }</pre>
</div>
<p>&#160;</p>
<p>Let us take a look from where this apply method is being called, first we will look at some actual domain behavior in the aggregate root.</p>
<div style="padding-bottom: 10px; margin: 0px; font-family: monaco,verdana; background: rgb(22,36,51); color: white; font-size: 10pt; overflow: scroll; padding-top: 10px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 1</span>&#160;<span style="color: #0080c0">public</span> <span style="color: #0080c0">void</span> Withdrawl(<span style="color: #2b91af">Amount</span> amount)</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 2</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 3</span>&#160;&#160;&#160;&#160; Guard();</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 4</span>&#160;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 5</span>&#160;&#160;&#160;&#160; IsBalanceHighEnough(amount);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 6</span>&#160;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 7</span>&#160;&#160;&#160;&#160; <span style="color: #0080c0">var</span> newBalance <span style="color: aqua">=</span> _balance<span style="color: aqua">.</span>Withdrawl(amount);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 8</span>&#160;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 9</span>&#160;&#160;&#160;&#160; Apply(<span style="color: #0080c0">new</span> <span style="color: #2b91af">CashWithdrawnEvent</span>(newBalance, amount));</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 10</span> }</pre>
</div>
<p></p>
<p>First we execute all our valuable domain logic, the business behavior. Then when we are satisfied that everything is ok and we know what type of state change we need to execute and we Apply a new domain event with the new internal state. The Apply method used here is a protected method on the BaseAgregateRoot. Btw there is nothing stating that there can only be one outcome, i.e. only one type of domain event being Applied.</p>
<div style="padding-bottom: 10px; margin: 0px; font-family: monaco,verdana; background: rgb(22,36,51); color: white; font-size: 10pt; overflow: scroll; padding-top: 10px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 1</span>&#160;<span style="color: #0080c0">protected</span> <span style="color: #0080c0">void</span> Apply<span style="color: aqua">&lt;</span>TEvent<span style="color: aqua">&gt;</span>(TEvent domainEvent) <span style="color: #0080c0">where</span> TEvent : <span style="color: #0080c0">class</span>, <span style="color: #2b91af">IDomainEvent</span></pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 2</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 3</span>&#160;&#160;&#160;&#160; domainEvent<span style="color: aqua">.</span>AggregateId <span style="color: aqua">=</span> Id;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 4</span>&#160;&#160;&#160;&#160; domainEvent<span style="color: aqua">.</span>Version <span style="color: aqua">=</span> GetNewEventVersion();</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 5</span>&#160;&#160;&#160;&#160; apply(domainEvent<span style="color: aqua">.</span>GetType(), domainEvent);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 6</span>&#160;&#160;&#160;&#160; _appliedEvents<span style="color: aqua">.</span>Add(domainEvent);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 7</span> }</pre>
</div>
<p></p>
<p>When we Apply a domain event we will first assign the aggregate root Id to the event so that we can keep track to which aggregate root this event belongs to. Secondly we get a new version and assign this to the event, this is to maintain the correct order of the events. Then we call the apply method which will make the state change to the aggregate root. And finally we will add this domain event to the internal list of applied events. This is very similar with the dirty check of NHibernate (the idea, not the actual implementation).</p>
<p>This is all what what is needed to execute domain behavior and keep track of the domain events that have been used to update internal state of an aggregate root. </p>
<h2>Getting the state changes</h2>
<p>So now we have build up some internal state changes and we want to persist them to some sort of medium. I am not going to discuss how to actually persist these state changes, that is for a later post, all I want to show you now is how to get them out of the aggregate root. How about we start with the method GetChanges <img src='http://elegantcode.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div style="padding-bottom: 10px; margin: 0px; font-family: monaco,verdana; background: rgb(22,36,51); color: white; font-size: 10pt; overflow: scroll; padding-top: 10px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 1</span>&#160;<span style="color: #2b91af">IEnumerable</span><span style="color: aqua">&lt;</span>IDomainEvent<span style="color: aqua">&gt;</span> IEventProvider<span style="color: aqua">.</span>GetChanges()</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 2</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 3</span>&#160;&#160;&#160;&#160; <span style="color: #0080c0">return</span> _appliedEvents</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 4</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: aqua">.</span>Concat(GetEntityEvents())</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 5</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: aqua">.</span>OrderBy(x <span style="color: aqua">=&gt;</span> x<span style="color: aqua">.</span>Version)</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 6</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: aqua">.</span>ToList();</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 7</span> }</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 8</span>&#160;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 9</span>&#160;<span style="color: #0080c0">private</span> <span style="color: #2b91af">IEnumerable</span><span style="color: aqua">&lt;</span>IDomainEvent<span style="color: aqua">&gt;</span> GetEntityEvents()</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 10</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 11</span>&#160;&#160;&#160;&#160; <span style="color: #0080c0">return</span> _entityEventProviders</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 12</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: aqua">.</span>SelectMany(entity <span style="color: aqua">=&gt;</span> entity<span style="color: aqua">.</span>GetChanges());</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 13</span> }</pre>
</div>
<p></p>
<p>Here we simply return all the applied domain events, by tracking these domain events we in effect track all the state changes that have happened since the aggregate root was instantiated. Here we also request all the applied domain events from all entities. Than new order the domain events by version. After having received and processed all the applied domain events we should Clear the aggregate root from all applied domain events so they won’t be persisted again.</p>
<div style="padding-bottom: 10px; margin: 0px; font-family: monaco,verdana; background: rgb(22,36,51); color: white; font-size: 10pt; overflow: scroll; padding-top: 10px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 1</span>&#160;<span style="color: #0080c0">void</span> <span style="color: #2b91af">IEventProvider</span><span style="color: aqua">.</span>Clear()</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 2</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 3</span>&#160;&#160;&#160;&#160; _entityEventProviders<span style="color: aqua">.</span>ForEach(x <span style="color: aqua">=&gt;</span> x<span style="color: aqua">.</span>Clear());</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 4</span>&#160;&#160;&#160;&#160; _appliedEvents<span style="color: aqua">.</span>Clear();</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 5</span> }</pre>
</div>
<p></p>
<p>Just a quick word about the entity event providers, in some cases you want to have domain behavior inside entities that are part of the aggregate but are not the aggregate root. Well in this case you want to have those entities generate domain events as well, and you want to get those as well when getting all changes. Same when clearing the domain also the changes inside each entity event provider should be cleared.</p>
<p>Before saving the changes in the aggregate root is finalized we also need to update the version of the aggregate root. This version will match the version of the last applied domain event.</p>
<h2>Loading historical domain events</h2>
<p>In a next post I’ll dig deeper into the event store but for now lets just assume you have a very nice way of storing these domain events and have the ability to retrieve them again. </p>
<p>As the IEventProvider interface nicely dictates there is a LoadFromHistory method that takes an IEnumerable&lt;IDomainEvent&gt; below here is the implementation of this method.</p>
<div style="padding-bottom: 10px; margin: 0px; font-family: monaco,verdana; background: rgb(22,36,51); color: white; font-size: 10pt; overflow: scroll; padding-top: 10px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 1</span>&#160;<span style="color: #0080c0">void</span> <span style="color: #2b91af">IEventProvider</span><span style="color: aqua">.</span>LoadFromHistory(<span style="color: #2b91af">IEnumerable</span><span style="color: aqua">&lt;</span><span style="color: #2b91af">IDomainEvent</span><span style="color: aqua">&gt;</span> domainEvents)</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 2</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 3</span>&#160;&#160;&#160;&#160; <span style="color: #0080c0">if</span> (domainEvents<span style="color: aqua">.</span>Count() <span style="color: aqua">==</span> <span style="color: yellow">0</span>)</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 4</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0080c0">return</span>;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 5</span>&#160;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 6</span>&#160;&#160;&#160;&#160; <span style="color: #0080c0">foreach</span> (<span style="color: #0080c0">var</span> domainEvent <span style="color: #0080c0">in</span> domainEvents)</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 7</span>&#160;&#160;&#160;&#160; {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 8</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; apply(domainEvent<span style="color: aqua">.</span>GetType(), domainEvent);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 9</span>&#160;&#160;&#160;&#160; }</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 10</span>&#160;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 11</span>&#160;&#160;&#160;&#160; Version <span style="color: aqua">=</span> domainEvents<span style="color: aqua">.</span>Last()<span style="color: aqua">.</span>Version;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 12</span>&#160;&#160;&#160;&#160; EventVersion <span style="color: aqua">=</span> Version;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 13</span> }</pre>
</div>
<p></p>
<p>When you take a look in the for each loop you will notice that here we are calling apply again, please note that this is the private variant which is responsible for updating the internal state of the aggregate root and that these events are not added to the _appliedEvents collection, nor is the Id or Version updated. We don’t want to save these events again. After applying all the historical domain events we update the aggregate root version to the version of the last event.</p>
<h2>The base class</h2>
<p>I am using a base class to provide this functionality to all the different aggregate roots using inheritance and I know there are different opinions about this. So I wanted to highlight that you can achieve the same results by using composition. Your aggregate roots still need to implement the interfaces, but the implementation can be provided by using composition.</p>
<p>An other thing is that all the public methods in the BaseAggregateRoot are explicate interface implementation. I do this because I want to hide these details for any piece of code that is using the aggregate root as is, only when dealing with persistence we use the interface and get access to the explicit interface methods. Nice and clean.</p>
<h2>Aggregate entities</h2>
<p>Ok I have already mentioned the term entities and entity event providers, and I would like to focus on them for a bit. An entity is an domain object that is part of the same aggregate as the aggregate root, but is not the aggregate root it self, is however it is managed by the aggregate root. We manage state changes in these entities in the exact same way as we do this in the aggregate root, so each entity is also an event provider. There is a different interface for the entities then for the aggregate root so they can not be confused among each other.</p>
<div style="padding-bottom: 10px; margin: 0px; font-family: monaco,verdana; background: rgb(22,36,51); color: white; font-size: 10pt; overflow: scroll; padding-top: 10px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 1</span>&#160;<span style="color: #0080c0">namespace</span> Fohjin<span style="color: aqua">.</span>DDD<span style="color: aqua">.</span>EventStore</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 2</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 3</span>&#160;&#160;&#160;&#160; <span style="color: #0080c0">public</span> <span style="color: #0080c0">interface</span> <span style="color: #2b91af">IEntityEventProvider</span> </pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 4</span>&#160;&#160;&#160;&#160; {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 5</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0080c0">void</span> Clear();</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 6</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0080c0">void</span> LoadFromHistory(<span style="color: #2b91af">IEnumerable</span><span style="color: aqua">&lt;</span><span style="color: #2b91af">IDomainEvent</span><span style="color: aqua">&gt;</span> domainEvents);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 7</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0080c0">void</span> HookUpVersionProvider(<span style="color: #2b91af">Func</span><span style="color: aqua">&lt;</span><span style="color: #0080c0">int</span><span style="color: aqua">&gt;</span> versionProvider);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 8</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">IEnumerable</span><span style="color: aqua">&lt;</span><span style="color: #2b91af">IDomainEvent</span><span style="color: aqua">&gt;</span> GetChanges();</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 9</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">Guid</span> Id { <span style="color: #0080c0">get</span>; }</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 10</span>&#160;&#160;&#160;&#160; }</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 11</span> }</pre>
</div>
<p></p>
<p>You may have also noticed the hookup version provider method, remember it <img src='http://elegantcode.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>The problem is that we should deal with the whole aggregate as a whole so all state changes need to be persisted within the same transaction. So we want to have a single point to access the internal state of the whole aggregate as well as a single point to load the history back into the whole aggregate. In order to achieve this the aggregate root needs to register all the entity event providers so it can track them. To enable that we have an additional interface for our aggregate root to implement.</p>
<div style="padding-bottom: 10px; margin: 0px; font-family: monaco,verdana; background: rgb(22,36,51); color: white; font-size: 10pt; overflow: scroll; padding-top: 10px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 1</span>&#160;<span style="color: #0080c0">namespace</span> Fohjin<span style="color: aqua">.</span>DDD<span style="color: aqua">.</span>EventStore</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 2</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 3</span>&#160;&#160;&#160;&#160; <span style="color: #0080c0">public</span> <span style="color: #0080c0">interface</span> <span style="color: #2b91af">IRegisterEntities</span></pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 4</span>&#160;&#160;&#160;&#160; {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 5</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0080c0">void</span> RegisterEntityEventProvider(<span style="color: #2b91af">IEntityEventProvider</span> entityEventProvider);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 6</span>&#160;&#160;&#160;&#160; }</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 7</span> }</pre>
</div>
<p></p>
<p>Lets look at the implementation right away</p>
<div style="padding-bottom: 10px; margin: 0px; font-family: monaco,verdana; background: rgb(22,36,51); color: white; font-size: 10pt; overflow: scroll; padding-top: 10px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 1</span>&#160;<span style="color: #0080c0">void</span> IRegisterEntities<span style="color: aqua">.</span>RegisterEntityEventProvider(IEntityEventProvider entityEventProvider)</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 2</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 3</span>&#160;&#160;&#160;&#160; entityEventProvider<span style="color: aqua">.</span>HookUpVersionProvider(GetNewEventVersion);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 4</span>&#160;&#160;&#160;&#160; _entityEventProviders<span style="color: aqua">.</span>Add(entityEventProvider);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 5</span> }</pre>
</div>
<p></p>
<p>Now this is only a very simple collection that hold references to IEntityEventProviders which is used in the previous shown GetEntityEvents method. So getting out the changes is relatively simple this way. I also created a special collection that will automatically register entities when they are added to the collection.</p>
<p>Remember I mentioned the HookUpVersionProvider method, well this is used to get a reference to the method from the aggregate root that deals with assigning a new version to each event. We want a reference to the same version generator that the aggregate root uses because then all the versions of each domain event will be in sequence independently is the aggregate root or an entity created it.</p>
<div style="padding-bottom: 10px; margin: 0px; font-family: monaco,verdana; background: rgb(22,36,51); color: white; font-size: 10pt; overflow: scroll; padding-top: 10px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 1</span>&#160;<span style="color: #0080c0">namespace</span> Fohjin<span style="color: aqua">.</span>DDD<span style="color: aqua">.</span>Domain</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 2</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 3</span>&#160;&#160;&#160;&#160; <span style="color: #0080c0">public</span> <span style="color: #0080c0">class</span> <span style="color: #2b91af">EntityList</span><span style="color: aqua">&lt;</span>TEntity<span style="color: aqua">&gt;</span> : <span style="color: #2b91af">List</span><span style="color: aqua">&lt;</span>TEntity<span style="color: aqua">&gt;</span> <span style="color: #0080c0">where</span> TEntity : IEntityEventProvider</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 4</span>&#160;&#160;&#160;&#160; {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 5</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0080c0">private</span> <span style="color: #0080c0">readonly</span> IRegisterEntities _aggregateRoot;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 6</span>&#160;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 7</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0080c0">public</span> EntityList(IRegisterEntities aggregateRoot)</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 8</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 9</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _aggregateRoot <span style="color: aqua">=</span> aggregateRoot;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 10</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 11</span>&#160;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 12</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0080c0">public</span> <span style="color: #0080c0">new</span> <span style="color: #0080c0">void</span> Add(TEntity entity)</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 13</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 14</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _aggregateRoot<span style="color: aqua">.</span>RegisterEntityEventProvider(entity);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 15</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0080c0">base</span><span style="color: aqua">.</span>Add(entity);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 16</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 17</span>&#160;&#160;&#160;&#160; }</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 18</span> }</pre>
</div>
<p></p>
<p>The collection takes a reference to the aggregate root it is part of in the constructor to be able to add each added entity event provider to the collection in the aggregate root.</p>
<p>Currently there is some duplication between the BaseAggregateRoot and the BaseEntity because they are inherited from different interfaces, I am sure there is some optimization possible there <img src='http://elegantcode.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>There is finally one more thing to cover about this and that is how historical domain events are being passed into the correct entity, currently this is a bit ugly but I am working on a more elegant solution. Take a look at the code.</p>
<div style="padding-bottom: 10px; margin: 0px; font-family: monaco,verdana; background: rgb(22,36,51); color: white; font-size: 10pt; overflow: scroll; padding-top: 10px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial">
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 1</span>&#160;<span style="color: #0080c0">private</span> <span style="color: #0080c0">void</span> registerEvents()</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 2</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 3</span>&#160;&#160;&#160;&#160; <span style="color: green">// Registration of Aggregate Root event handlers</span></pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 4</span>&#160;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 5</span>&#160;&#160;&#160;&#160; RegisterEvent<span style="color: aqua">&lt;</span>BankCardWasReportedStolenEvent<span style="color: aqua">&gt;</span>(onAnyEventForABankCard);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 6</span>&#160;&#160;&#160;&#160; RegisterEvent<span style="color: aqua">&lt;</span>BankCardWasCanceledByCLientEvent<span style="color: aqua">&gt;</span>(onAnyEventForABankCard);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 7</span> }</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 8</span>&#160;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160;&#160; 9</span>&#160;<span style="color: #0080c0">private</span> <span style="color: #0080c0">void</span> onAnyEventForABankCard(IDomainEvent domainEvent)</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 10</span> {</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 11</span>&#160;&#160;&#160;&#160; IEntityEventProvider bankCard;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 12</span>&#160;&#160;&#160;&#160; <span style="color: #0080c0">if</span> (<span style="color: aqua">!</span>_bankCards<span style="color: aqua">.</span>TryGetValueById(domainEvent<span style="color: aqua">.</span>AggregateId, <span style="color: #0080c0">out</span> bankCard))</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 13</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0080c0">throw</span> <span style="color: #0080c0">new</span> <span style="color: #2b91af">NonExistingBankCardException</span>(<span style="color: #a31515">&quot;The requested bank card does not exist!&quot;</span>);</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 14</span>&#160;</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 15</span>&#160;&#160;&#160;&#160; bankCard<span style="color: aqua">.</span>LoadFromHistory(<span style="color: #0080c0">new</span>[] { domainEvent });</pre>
<pre style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; background: rgb(22,36,51); padding-top: 0px"><span style="background: #121e31">&#160;&#160; 16</span> }</pre>
</div>
<p></p>
<p>So each entity domain event will be registered here as well and are all passed to one specific event handler (one specific event handler for each different entity type). What happens is that we check if the specific event provider is present in the collection by looking for the Id, when the requested event provider is found the historical domain event will be loaded using the load from history method on the event provider. </p>
<p>The problem here is that the information which events the entity can produce is already registered, and that is in the entities them self&#8217;s. So by making that information statically available I should be able to auto register the entity event handlers.</p>
<h2>Finally</h2>
<p>I hope that this was a useful explanation of how the aggregate root works with the internal domain events, and that you would agree with me that it really is not very difficult. Next time I want to discuss the event store so we can take a look at persisting the domain events. I will also post a blog about making the entity registration more elegant and less manual work.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=mMKbfitPDl4:TUfcavCta2I:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=mMKbfitPDl4:TUfcavCta2I:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=mMKbfitPDl4:TUfcavCta2I:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=mMKbfitPDl4:TUfcavCta2I:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=mMKbfitPDl4:TUfcavCta2I:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=mMKbfitPDl4:TUfcavCta2I:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/mMKbfitPDl4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/11/20/cqrs-the-domain-events/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Review Amazon Kindle DX</title>
		<link>http://elegantcode.com/2009/11/20/review-amazon-kindle-dx/</link>
		<comments>http://elegantcode.com/2009/11/20/review-amazon-kindle-dx/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 23:25:48 +0000</pubDate>
		<dc:creator>Jan Van Ryswyck</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[Esoterica]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/11/20/review-amazon-kindle-dx/</guid>
		<description><![CDATA[ 
As my bookshelf has grown out of proportion over the last years, I basically had two options left. First option was to build an extra room onto my house that could serve as a private library, which is kind of expensive. Second option was to the reduce the amount of paper by buying an [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://elegantcode.com/wp-content/uploads/2009/11/kindle_dx.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="kindle_dx" border="0" alt="kindle_dx" align="left" src="http://elegantcode.com/wp-content/uploads/2009/11/kindle_dx_thumb.jpg" width="218" height="320" /></a> </p>
<p>As <a href="http://www.shelfari.com/o1518100500/shelf">my bookshelf</a> has grown out of proportion over the last years, I basically had two options left. First option was to build an extra room onto my house that could serve as a private library, which is kind of expensive. Second option was to the reduce the amount of paper by buying an eReader device. I chose to investigate the second option. I already heard and read a lot of nice things about the Amazon Kindle, especially the Kindle DX.</p>
<p>As you may or may not know, these devices were not available in Europe until about a month ago Amazon announced that they will make the <a href="http://www.amazon.com/exec/obidos/ASIN/B0015T963C/elegantcode-20">Kindle 2</a> available outside the US. But what I really wanted was the <a href="http://www.amazon.com/exec/obidos/ASIN/B0015TCML0/elegantcode-20">Kindle DX</a> because it seemed to provide good support for PDF documents while the Kindle 2 doesn’t support this format at all. I already had a couple of eBooks in PDF format, so that was the most obvious choice for me. I also checked with the major book publishers and most of them also provide the native Kindle (AZW) and <a href="http://en.wikipedia.org/wiki/Mobipocket">Mobi</a> formats (beside PDF). </p>
<p>The only problem left was to get a Kindle DX to Belgium. Luckily <a href="http://elegantcode.com/about/david-starr/">David</a> and <a href="http://domesticoblivion.com/">Elle</a> were happy to help me out on this one (many thanks). And so, since a couple of weeks I’m a proud owner of a Kindle DX. I must say that I really like the experience so far.</p>
<p>I wanted to read both novels and technical books using this device. The 9.7” e-ink screen (no backlit or LCD) provides a pleasant reading experience. At first, I was afraid that some documents wouldn’t be as readable due to the fixed format of PDF. But thus far, the Kindle DX seems to solve this very elegantly. Getting a PDF documents on the device is as easy as you’ve come to expect. Just hook it up on your PC using USB, copy the files and you’re good to go.</p>
<p>The size of the Kindle DX can be compared to a regular technical book. Its also incredibly thin and it definitely doesn’t weigh as much as some books.</p>
<p><a href="http://elegantcode.com/wp-content/uploads/2009/11/kindle_dx_4.jpg"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="kindle_dx_4" border="0" alt="kindle_dx_4" src="http://elegantcode.com/wp-content/uploads/2009/11/kindle_dx_4_thumb.jpg" width="256" height="218" /></a> </p>
<p>The amount of storage is amazing. I can practically put my entire library on there without running out of space. It also has a very long battery life. I’ve been using it for about two weeks now and so far I did not have to recharge the battery. </p>
<p>Skimming through a book does take some time. You can’t beat a paper book on that one. But the search capabilities are very neat and it’s also possible to search in multiple books (which again is rather difficult with paper books).&#160; You can place bookmarks its possible to go to a specific page number. The experience of going to a next or previous page was a bit odd at first, but I got used to that after a couple of hours. With auto-rotation, you can read a document in portrait or landscape. The only downside is that the experience is not as fluent as with an iPhone or iPod Touch because sometimes it can take a couple of seconds to adjust. Below are some pictures of my Kindle DX in order to get a sense of the PDF support that it provides:</p>
<p align="center">&#160;<a href="http://elegantcode.com/wp-content/uploads/2009/11/SOA.jpg"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="SOA" border="0" alt="SOA" src="http://elegantcode.com/wp-content/uploads/2009/11/SOA_thumb.jpg" width="395" height="520" /></a> Enterprise SOA Adoption Strategies (InfoQ)</p>
<p align="left">&#160;</p>
<p align="center"><a href="http://elegantcode.com/wp-content/uploads/2009/11/IMG_5903.jpg"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="IMG_5903" border="0" alt="IMG_5903" src="http://elegantcode.com/wp-content/uploads/2009/11/IMG_5903_thumb.jpg" width="395" height="519" /></a>C# in Depth</p>
<p align="center">&#160;<a href="http://elegantcode.com/wp-content/uploads/2009/11/NH.jpg"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="NH" border="0" alt="NH" src="http://elegantcode.com/wp-content/uploads/2009/11/NH_thumb.jpg" width="395" height="519" /></a>&#160;&#160; NHibernate in Action</p>
<p>&#160;</p>
<p align="center"><a href="http://elegantcode.com/wp-content/uploads/2009/11/ASP.jpg"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="ASP" border="0" alt="ASP" src="http://elegantcode.com/wp-content/uploads/2009/11/ASP_thumb.jpg" width="396" height="522" /></a>ASP.NET MVC in Action </p>
<p>I haven’t tried the text-to-speech feature and wireless support. I also need to check out the support for audio books and the ability to make notes while reading. I think the most obvious new feature for a next version of the Kindle DX would be a color touch screen. That would make the whole experience even better.</p>
<p>Bottom line, compared to the Kindle 2, the Kindle DX is a no brainer. If you’re able to spend the extra money, you won’t regret it. The PDF support and the large screen are definitely worth it.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=5ZGHJuiUYhc:slY7qwi8nM8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=5ZGHJuiUYhc:slY7qwi8nM8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=5ZGHJuiUYhc:slY7qwi8nM8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=5ZGHJuiUYhc:slY7qwi8nM8:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=5ZGHJuiUYhc:slY7qwi8nM8:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=5ZGHJuiUYhc:slY7qwi8nM8:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/5ZGHJuiUYhc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/11/20/review-amazon-kindle-dx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Silverlight 4 WebCam – at a glance</title>
		<link>http://elegantcode.com/2009/11/20/silverlight-4-webcam-a-quick-glance/</link>
		<comments>http://elegantcode.com/2009/11/20/silverlight-4-webcam-a-quick-glance/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 10:08:12 +0000</pubDate>
		<dc:creator>cschuman</dc:creator>
				<category><![CDATA[Esoterica]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/11/20/silverlight-4-webcam-a-quick-glance/</guid>
		<description><![CDATA[WebCam support in Silverlight 4 is a much anticipated feature, and probably didn’t come as much of a surprise.&#160; It’s relatively simple to enable this feature.&#160; The below example shows a simple UI with the code to enable the webcam.&#160; This post does not cover multiple webcams, however calling CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices returns a list of all [...]]]></description>
			<content:encoded><![CDATA[<p>WebCam support in Silverlight 4 is a much anticipated feature, and probably didn’t come as much of a surprise.&#160; It’s relatively simple to enable this feature.&#160; The below example shows a simple UI with the code to enable the webcam.&#160; This post does not cover multiple webcams, however calling <strong>CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices</strong> returns a list of all available webcams.</p>
<p>First create a simple UI (a <strong>Rectangle</strong> and a <strong>Button</strong>).</p>
<p><a href="http://elegantcode.com/wp-content/uploads/2009/11/image3.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://elegantcode.com/wp-content/uploads/2009/11/image_thumb3.png" width="600" height="320" /></a> </p>
<p>Add an event to the button click event.&#160; The logic looks like this:</p>
<ul>
<li>Get a handle on your video capture device using <strong>CaptureDeviceConfiguration</strong>. </li>
<li>Request access to the device with <strong>CaptureDeviceConfiguration.RequestDeviceAccess()</strong>. </li>
<li>If the user clicks Yes, then create a <strong>CaptureSource</strong> object and set the <strong>VideoCaptureDevice </strong>to the selected webcam. </li>
<li>Create a <strong>VideoBrush</strong> </li>
<li>Set the Source of the <strong>VideoBrush</strong> </li>
<li>Start the webcam </li>
<li>Paint the Rectangle (this could be anything that takes a Brush) </li>
</ul>
<p><a href="http://elegantcode.com/wp-content/uploads/2009/11/image4.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://elegantcode.com/wp-content/uploads/2009/11/image_thumb4.png" width="600" height="350" /></a> </p>
<p>Next step, F5 (run your app).&#160; You’ll be looking at a blank screen with a button.&#160; After clicking the button, a box appears prompting the user to allow access to the webcam and microphone.&#160; Click Yes, since after all that is our goal <img src='http://elegantcode.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p><a href="http://elegantcode.com/wp-content/uploads/2009/11/image5.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://elegantcode.com/wp-content/uploads/2009/11/image_thumb5.png" width="564" height="217" /></a> </p>
<p><strong>Voilà!!</strong> You are now looking at yourself. Now you can do all sorts of fun web cam stuff.&#160; Enjoy.</p>
<p><a href="http://elegantcode.com/wp-content/uploads/2009/11/image6.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://elegantcode.com/wp-content/uploads/2009/11/image_thumb6.png" width="505" height="531" /></a> </p>
<h3>Tip</h3>
<p>After running the above app, I noticed it was <em>backwards</em>.&#160; Meaning when I moved left my face on the screen moved to my right.&#160; Maybe it’s just me, but my brain was not happy about this.&#160; Instead, I wanted the app to respond like a mirror.&#160; To do this was a quick fix; simply <strong>Flip</strong> the Rectangle on the X axis.&#160; Here is the menu in Blend to do this:</p>
<p><a href="http://elegantcode.com/wp-content/uploads/2009/11/image7.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://elegantcode.com/wp-content/uploads/2009/11/image_thumb7.png" width="262" height="147" /></a> </p>
<h3>More info</h3>
<p>For more information, Tim Heuer has a great video covering Web cam and microphone support in detail: <a href="http://silverlight.net/learn/videos/all/access-web-camera-microphone/">http://silverlight.net/learn/videos/all/access-web-camera-microphone/</a></p>
<p> <a href="http://silverlight.net/learn/videos/all/access-web-camera-microphone/"></a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=EUXuDc_rr9U:GVokEUvPrVw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=EUXuDc_rr9U:GVokEUvPrVw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=EUXuDc_rr9U:GVokEUvPrVw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=EUXuDc_rr9U:GVokEUvPrVw:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=EUXuDc_rr9U:GVokEUvPrVw:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=EUXuDc_rr9U:GVokEUvPrVw:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/EUXuDc_rr9U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/11/20/silverlight-4-webcam-a-quick-glance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Recording of my E-VAN presentation about CQRS</title>
		<link>http://elegantcode.com/2009/11/19/recording-of-my-e-van-presentation-about-cqrs/</link>
		<comments>http://elegantcode.com/2009/11/19/recording-of-my-e-van-presentation-about-cqrs/#comments</comments>
		<pubDate>Thu, 19 Nov 2009 20:11:37 +0000</pubDate>
		<dc:creator>Mark Nijhof</dc:creator>
				<category><![CDATA[CQRS]]></category>
		<category><![CDATA[DDD]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/11/19/recording-of-my-e-van-presentation-about-cqrs/</guid>
		<description><![CDATA[Jan van Ryswyck put again a great deal of effort into getting the E-VAN recording of my CQRS presentation uploaded so quickly. We are only talking about one day, almost seems like he has nothing else to do   Thanks Jan!
Unfortunately the quality of the recording is very low, instead of the Vimeo version [...]]]></description>
			<content:encoded><![CDATA[<p>Jan van Ryswyck put again a great deal of effort into getting the E-VAN recording of my CQRS presentation uploaded so quickly. We are only talking about one day, almost seems like he has nothing else to do <img src='http://elegantcode.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Thanks Jan!</p>
<p>Unfortunately the quality of the recording is very low, instead of the Vimeo version you might actually want to get the Live meeting version. </p>
<p>The recording can be found here: <a href="http://www.vimeo.com/7708616">http://www.vimeo.com/7708616</a></p>
<p>The original version here: <a title="https://www323.livemeeting.com/cc/usergroups/view?id=van-41" href="https://www323.livemeeting.com/cc/usergroups/view?id=van-41">https://www323.livemeeting.com/cc/usergroups/view?id=van-41</a></p>
<p>The code that the presentation covers can be found here: <a href="http://github.com/MarkNijhof/Fohjin">http://github.com/MarkNijhof/Fohjin</a></p>
<p>I hope that many will provide their feedback, both good and bad as this is how I evolve. </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=gVI4q5Z5fqY:FncLPMuZJiE:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=gVI4q5Z5fqY:FncLPMuZJiE:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=gVI4q5Z5fqY:FncLPMuZJiE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=gVI4q5Z5fqY:FncLPMuZJiE:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=gVI4q5Z5fqY:FncLPMuZJiE:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=gVI4q5Z5fqY:FncLPMuZJiE:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/gVI4q5Z5fqY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/11/19/recording-of-my-e-van-presentation-about-cqrs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code Cast 34 – David Starr Sells Out to the Man</title>
		<link>http://elegantcode.com/2009/11/17/ecc-34-david-starr-sells-out-to-the-man/</link>
		<comments>http://elegantcode.com/2009/11/17/ecc-34-david-starr-sells-out-to-the-man/#comments</comments>
		<pubDate>Tue, 17 Nov 2009 19:13:41 +0000</pubDate>
		<dc:creator>Chris Brandsma</dc:creator>
				<category><![CDATA[CodeCast]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/11/17/ecc-34-david-starr-sells-out-to-the-man/</guid>
		<description><![CDATA[OK, bitter-sweet podcast here, this is Daddy Starr’s final podcast with the Elegant Code Cast.&#160; Why?&#160; Well, you will just have to listen to find that out.
In the mean time, we also talk about Agile, LEAN, working agile methodologies in with family life, and his new company: Guild 3.&#160; Have a listen and tell us [...]]]></description>
			<content:encoded><![CDATA[<p>OK, bitter-sweet podcast here, this is Daddy Starr’s final podcast with the Elegant Code Cast.&#160; Why?&#160; Well, you will just have to listen to find that out.</p>
<p>In the mean time, we also talk about Agile, LEAN, working agile methodologies in with family life, and his new company: Guild 3.&#160; Have a listen and tell us what you think.</p>
<p>Links from the Show:</p>
<ul>
<li><a title="http://guild3.com/" href="http://guild3.com/">Guild 3 Software</a> </li>
<li><a href="http://elegantcode.com/2009/08/31/code-cast-31-agile-for-families/">Agile for Families</a> </li>
<li><a href="http://PluralSight.com">PluralSight</a> </li>
<li><a href="http://www.pluralsight.com/main/pluralcast/default.aspx">PluralCast</a></li>
</ul>
<p><a href="http://pluralsight-elegant.s3.amazonaws.com/ECC_34_DavidStarr.mp3">Link to show</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=Cie98ds50KQ:iGQ6XPpWHnA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=Cie98ds50KQ:iGQ6XPpWHnA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=Cie98ds50KQ:iGQ6XPpWHnA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=Cie98ds50KQ:iGQ6XPpWHnA:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=Cie98ds50KQ:iGQ6XPpWHnA:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=Cie98ds50KQ:iGQ6XPpWHnA:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/Cie98ds50KQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/11/17/ecc-34-david-starr-sells-out-to-the-man/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
<enclosure url="http://pluralsight-elegant.s3.amazonaws.com/ECC_34_DavidStarr.mp3" length="36532858" type="audio/mpeg" />
		</item>
		<item>
		<title>PDC Notes</title>
		<link>http://elegantcode.com/2009/11/17/pdc-notes/</link>
		<comments>http://elegantcode.com/2009/11/17/pdc-notes/#comments</comments>
		<pubDate>Tue, 17 Nov 2009 17:23:30 +0000</pubDate>
		<dc:creator>David Starr</dc:creator>
				<category><![CDATA[Microsoft]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/11/17/pdc-notes/</guid>
		<description><![CDATA[I am grateful to INETA to be attending PDC this year. Also, I grateful to Visual Stuart, who is letting me crash in his room. Turns out, I am a cheap skate  
I am sitting in the keynote on Tuesday and thinking about the week. In addition to the 
Wait? What the… Wordpress moving [...]]]></description>
			<content:encoded><![CDATA[<p>I am grateful to INETA to be attending <a href="http://microsoftpdc.com">PDC</a> this year. Also, I grateful to <a href="http://visualstuart.com">Visual Stuart</a>, who is letting me crash in his room. Turns out, I am a cheap skate <img src='http://elegantcode.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I am sitting in the keynote on Tuesday and thinking about the week. In addition to the </p>
<blockquote><p><font style="background-color: #ffffff">Wait? What the… Wordpress moving into the Azure cloud? Sweet!</font></p>
</blockquote>
<p>volunteer sessions I am doing for INETA, I am hosting a Birds of a Feather session with Mike Vincent. Our BOF is this afternoon and is entitled, “Agile Tales of Triumph, Tribulation, Tools, and Teams”. Drop by and join the discussion to learn </p>
<blockquote><p><font style="background-color: #ffffff">Code name Dallas: A uniform way to access data in the cloud and mash it all up.</font></p>
</blockquote>
<p>and share what really works.</p>
<p>It has been very cool to meet many of the Pluralsight instructors for the first time. We all live in different parts of the world, and PDC provides that opportunity for us to </p>
<blockquote><p>Everyone get your 3D glasses on! Oh, that was very anti-climactic.</p>
</blockquote>
<p>all actually shake physical hands rather than electronic ones.</p>
<p>Also, drop by the Pluralsight booth and share your developer stories with me. Here’s the sneak peek as to why: <font style="background-color: #ffffff"><a href="http://www.pluralsight.com/main/pluralcast/default.aspx">Pluralcast</a>. More on that in another post. Suffice </font></p>
<blockquote><p><font style="background-color: #ffffff">I think that guy onstage is showing an iPhone and talking about how easy it was to write an app for it. Weird.</font></p>
</blockquote>
<p><font style="background-color: #ffffff">to say </font>there will be some changes in the Elegant Code Cast.</p>
<blockquote><p>Did he just say, “Create applications for the good of the republic?” Seriously?</p>
</blockquote>
<p>Lastly, if you see me running around the halls, please stop me and say, Hello.” It’s very cool to be able to meet people I usually only get to chat with online. If you are looking for a <a href="http://guild3.com">great developer team</a> to build your next big thing, we can talk about that, too!</p>
<blockquote><p>Please stop saying “3 screens in the cloud.”</p>
</blockquote>
<p>Ray Ozzie final points from the keynote:</p>
<ol>
<li>Bet your next user experience on Windows 7</li>
<li>When thinking of the cloud, bet on Azure.</li>
<li>Take a moment to think about how the world is changing and the potential role of cloud in that world.</li>
</ol>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=3wkYMfozRAE:E6kIz5ZUsy0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=3wkYMfozRAE:E6kIz5ZUsy0:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=3wkYMfozRAE:E6kIz5ZUsy0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=3wkYMfozRAE:E6kIz5ZUsy0:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=3wkYMfozRAE:E6kIz5ZUsy0:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=3wkYMfozRAE:E6kIz5ZUsy0:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/3wkYMfozRAE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/11/17/pdc-notes/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Azure Summary</title>
		<link>http://elegantcode.com/2009/11/16/azure-summary/</link>
		<comments>http://elegantcode.com/2009/11/16/azure-summary/#comments</comments>
		<pubDate>Tue, 17 Nov 2009 05:30:14 +0000</pubDate>
		<dc:creator>Tony Rasa</dc:creator>
				<category><![CDATA[Esoterica]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/11/16/azure-summary/</guid>
		<description><![CDATA[I was asked today, “what’s this whole ‘Microsoft Azure’ thing about?”&#160; I haven’t done anything with Azure, EC2, or Google Apps Engine, but why let my ignorance stop me from blogging about it?&#160; So here’s a brief summary of what I understand about these cloud technologies – I find the whole idea fascinating and am [...]]]></description>
			<content:encoded><![CDATA[<p>I was asked today, “what’s this whole ‘Microsoft Azure’ thing about?”&#160; I haven’t done anything with Azure, EC2, or Google Apps Engine, but why let my ignorance stop me from blogging about it?&#160; So here’s a brief summary of what I understand about these cloud technologies – I find the whole idea fascinating and am looking for an excuse to do more with one of these implementations.&#160;&#160; Consider this a plea for my friends, the Elegant Code Peanut Gallery, to help bring understanding to us all.</p>
<h4>The tl;dr version</h4>
<p>Azure involves a classic tradeoff: being able to scale very effectively and not having to make major capital investments, vs. having to pay more to your cloud computing environment for the convenience of it.&#160; It’s suitable for some applications and businesses, but certainly not all.&#160; To make the most of it, you should (or, must) architect your application around the whole cloud-notion to begin with.&#160; How much, and how bad it’ll hurt, depends on platform and your application.</p>
<h4>The Long Winded Version</h4>
<p>Let’s say you’re a big online retailer, selling books online (as an example I just made up).&#160;&#160;&#160; For 3 months of the year, your servers are completely slammed with orders – you need lots of bandwidth, lots of CPU, everything.&#160; I’m talking about renting out a big data center for $BidMoney a month, hiring SysAdmins, NetAdmins, all of that.&#160;&#160;&#160; The other 9 months of the year, its boring.&#160; You could just have a server under your desk, and hire some high school kid to keep it running.</p>
<p>This is why Amazon’s EC2 was invented (and why Microsoft is competing with them with Azure).&#160;&#160; Rather than buying racks of servers, hiring staff to keep it running, and so on &#8211; for stuff that you won’t need for most of the year, you deploy your application to Azure – when times are busy, you spool up additional servers easily.&#160; When the rush is over, just throw those extra instances away.</p>
<p>Your startup get mentioned in the WSJ?&#160; Add servers to deal with the traffic, so you don’t look stupid with “Server Unavailable” errors.&#160; Any sort of business model that is built around ‘bursts’ makes a lot of sense for this.</p>
<p>The tradeoff:&#160; Cost.&#160; You pay for CPU time, storage space, transactions, bandwidth.&#160; Each of these are really small numbers like “$0.15 / GB stored / month” and “$0.01 / 10k transactions” but they can add up quickly &#8211; a Death of a Thousand Cuts.&#160; Plus, with EC2 and Azure, the CPU time is not “cpu time doing something useful,” it is “<a href="http://www.microsoft.com/windowsazure/pricing/" target="_blank">amount of hours the virtual server was running</a>.”&#160;&#160; So if your app spends most of its time doing nothing…</p>
<p>For a small app with little traffic, this could add up to $100s / month, instead of just paying $VeryLittle/month for really lousy shared hosting, or a little more for less-lousy virtual hosting.&#160;&#160; And as I understand it, all of these services are “No Refunds” so if you get hit with a big wave of traffic, or forget to turn a server off when you were done with it, or whatever, … too bad, pay up!&#160; </p>
<p>It’s not all bad though – Google App Engine is free for 500 MB of storage and 5 million page views, and when you’re ready for more you can set up a quota and daily budget so you don’t get any nasty surprises.&#160; And while Azure is in CTP, its without charge (with a few modest quotas applied).&#160; So, you can start writing your Facebook-killer app right now, and deal with the costs later <img src='http://elegantcode.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h4>Application Design</h4>
<p>With Google App Engine and Amazon EC2, and mostly with Microsoft Azure, you must design your applications with cloud operation up front.&#160; It’s not exactly trivial to take an app written for a more traditional web server/database structure and deploy it to the cloud: you should be using the cloud’s data access APIs, not storing anything on the server itself, and have ways to get your data to and from the cloud (racking up transaction fees in the process).&#160; And don’t forget that your data is out there in hostile territory – how are you going to <a href="http://techboise.com/hows-your-crypto" target="_blank">keep it safe</a>?&#160; Plus your choice of cloud dictates what languages and platforms you can choose from.</p>
<p>I said “mostly” because with Azure you can pay a little extra to get access to “SQL Azure” if you need relational database storage.&#160; Which I think is great, although you’d have to balance those costs against the effort of using a more transaction based storage model.</p>
<p>&#160;</p>
<p>So there you go, a tiny bit of understanding packed into a dangerous form of leaping conclusions.&#160; <img src='http://elegantcode.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=Ckk0jSdooVU:IPAAu5IrDV4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=Ckk0jSdooVU:IPAAu5IrDV4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=Ckk0jSdooVU:IPAAu5IrDV4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=Ckk0jSdooVU:IPAAu5IrDV4:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=Ckk0jSdooVU:IPAAu5IrDV4:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=Ckk0jSdooVU:IPAAu5IrDV4:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/Ckk0jSdooVU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/11/16/azure-summary/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why Future&lt;T&gt; should be in your future</title>
		<link>http://elegantcode.com/2009/11/16/why-futuret-should-be-in-your-future/</link>
		<comments>http://elegantcode.com/2009/11/16/why-futuret-should-be-in-your-future/#comments</comments>
		<pubDate>Mon, 16 Nov 2009 17:50:24 +0000</pubDate>
		<dc:creator>Jason Grundy</dc:creator>
				<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/11/16/why-futuret-should-be-in-your-future/</guid>
		<description><![CDATA[Even though NHibernate 3.0 is on the way I am going to highlight a feature that was introduced in v2.1 but that relatively few people seem to be using (at least in the code bases I have seen recently). Former ECer Davy Brion, as always, does an excellent job of demonstrating usage of the feature [...]]]></description>
			<content:encoded><![CDATA[<p>Even though NHibernate 3.0 is on the way I am going to highlight a feature that was introduced in v2.1 but that relatively few people seem to be using (at least in the code bases I have seen recently). Former ECer Davy Brion, as always, does an excellent job of demonstrating usage of the feature <a href="http://davybrion.com/blog/2009/01/nhibernate-and-future-queries/">here</a> so I am not going to rehash that. What I am going to focus on here if the why.</p>
<p>Building a UI can be a very database intensive operation in terms of the number of separate calls required. And for each one of those calls the time taken to actually execute the query can be a small compared to the duration of the roundtrip to request and fetch the data. The obvious solution is some type of batching and with Future&lt;T&gt; this happens automagically without any change to the consuming logic (for databases that support it). Let me restate that, you get a huge performance benefit with only a simple change to your query methods in the Repository. So why aren’t you using it?</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=ittNzczYFRM:i2flu694W24:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=ittNzczYFRM:i2flu694W24:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=ittNzczYFRM:i2flu694W24:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=ittNzczYFRM:i2flu694W24:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=ittNzczYFRM:i2flu694W24:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=ittNzczYFRM:i2flu694W24:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/ittNzczYFRM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/11/16/why-futuret-should-be-in-your-future/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Follow me @ Elegant Code</title>
		<link>http://elegantcode.com/2009/11/15/follow-me-elegant-code/</link>
		<comments>http://elegantcode.com/2009/11/15/follow-me-elegant-code/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 17:24:16 +0000</pubDate>
		<dc:creator>Mark Nijhof</dc:creator>
				<category><![CDATA[Esoterica]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/11/15/follow-me-elegant-code/</guid>
		<description><![CDATA[I have been invited to join the bloggers at Elegant Code and as you can see I happily accepted! It is nice to be in the presence of other Elegant Coders (al do I can’t say for sure because I haven’t seen everyone&#8217;s profile picture yet) instead of being on my own. I hope that [...]]]></description>
			<content:encoded><![CDATA[<p>I have been invited to join the bloggers at Elegant Code and as you can see I happily accepted! It is nice to be in the presence of other Elegant Coders (al do I can’t say for sure because I haven’t seen everyone&#8217;s profile picture yet) instead of being on my own. I hope that I can reach more developers interested in writing Elegant Code, trying to make a small positive change.</p>
<p>I will also bring some (or maybe all) of my previous posts under here as I like to keep things nicely together. I’ll leave the old blog up for a while so the existing comments don’t disappear.</p>
<p>Finally I am looking forward to your critical input so I can continue to improve myself <img src='http://elegantcode.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>You can contact me: <a href="mailto:Mark.Nijhof@Gmail.com">Mark.Nijhof@Gmail.com</a> or via Twitter <a href="http://twitter.com/MarkNijhof">@MarkNijhof</a> you can still use the same feed url <a href="http://feeds.feedburner.com/Fohjin">Fohjin.com @ Elegant Code</a> as I changed it to point to my Elegant Code feed. My Elegant Code profile is <a href="http://elegantcode.com/about/mark-nijhof/">here</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=yTRhygKjI-Q:TJf4eBXzwnI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=yTRhygKjI-Q:TJf4eBXzwnI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=yTRhygKjI-Q:TJf4eBXzwnI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=yTRhygKjI-Q:TJf4eBXzwnI:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=yTRhygKjI-Q:TJf4eBXzwnI:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=yTRhygKjI-Q:TJf4eBXzwnI:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/yTRhygKjI-Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/11/15/follow-me-elegant-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Enum conversion. Why Oh Why?</title>
		<link>http://elegantcode.com/2009/11/15/enum-conversion-why-oh-why/</link>
		<comments>http://elegantcode.com/2009/11/15/enum-conversion-why-oh-why/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 07:02:03 +0000</pubDate>
		<dc:creator>Jason Jarrett</dc:creator>
				<category><![CDATA[Esoterica]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/11/15/enum-conversion-why-oh-why/</guid>
		<description><![CDATA[ 
&#160;
What MSDN says: enum (C# Reference)

&#160;
Why can’t this just work?
]]></description>
			<content:encoded><![CDATA[<p><a href="http://elegantcode.com/wp-content/uploads/2009/11/image1.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://elegantcode.com/wp-content/uploads/2009/11/image_thumb1.png" width="569" height="364" /></a> </p>
<p>&#160;</p>
<p>What MSDN says: <a href="http://msdn.microsoft.com/en-us/library/sbbt4032.aspx">enum (C# Reference)</a></p>
<p><a href="http://elegantcode.com/wp-content/uploads/2009/11/image2.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://elegantcode.com/wp-content/uploads/2009/11/image_thumb2.png" width="572" height="134" /></a></p>
<h4>&#160;</h4>
<p>Why can’t this just work?</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=lbT9XcTGubQ:DTr-B8UC2hY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=lbT9XcTGubQ:DTr-B8UC2hY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=lbT9XcTGubQ:DTr-B8UC2hY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=lbT9XcTGubQ:DTr-B8UC2hY:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=lbT9XcTGubQ:DTr-B8UC2hY:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=lbT9XcTGubQ:DTr-B8UC2hY:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/lbT9XcTGubQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/11/15/enum-conversion-why-oh-why/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
