<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.thinkbeforecoding.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en">
  
  <title type="html">Think Before Coding</title>
  <subtitle type="html" />
  
  <link href="http://thinkbeforecoding.com/" rel="alternate" type="text/html" title="" />
  <updated>2010-08-17T02:26:03+02:00</updated>
  <author>
    <name>Jérémie Chassaing</name>
  </author>
  <id>urn:md5:18477</id>
  <generator uri="http://www.dotclear.net/">Dotclear</generator>
  
    
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.thinkbeforecoding.com/ThinkBeforeCoding" /><feedburner:info uri="thinkbeforecoding" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.thinkbeforecoding.com/ThinkBeforeCoding" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsalloy.com/?rss=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://www.newsalloy.com/subrss3.gif">Subscribe with NewsAlloy</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://www.yourminis.com/subscribe.aspx?u=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://www.yourminis.com/images/addtoyourminisbadge.gif">Subscribe with Yourminis.com</feedburner:feedFlare><feedburner:feedFlare href="http://download.attensa.com/app/get_attensa.html?feedurl=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://www.attensa.com/blogs/attensa/WindowsLiveWriter/BadgeredintoBadges_10C02/attensa_feed_button5.gif">Subscribe with Attensa for Outlook</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://hub.netomat.net/account/account.autoSubscribe.jspa?urls=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://www.netomat.net/blogger/images/icon_netomat_feedbutton.gif">Subscribe with netomat Hub</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.flurry.com/pushRssFeed.do?r=fb&amp;url=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://www.flurry.com/images/flurry_rss_logo2.gif">Subscribe with Flurry</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.thinkbeforecoding.com%2FThinkBeforeCoding" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><entry>
    <title>DDD Exchange 2010</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/A3UntyhJdEA/DDD-Exchange-2010" rel="alternate" type="text/html" title="DDD Exchange 2010" />
    <id>urn:md5:022c0a1bb08d0f8fea5c89428744a542</id>
    <updated>2010-06-14T10:58:00+02:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>Domain Driven Design</dc:subject>
        <dc:subject>CQRS</dc:subject><dc:subject>DDD Exchange</dc:subject><dc:subject>Distributed Domain Driven Design</dc:subject><dc:subject>Domain Driven Design</dc:subject><dc:subject>Evans</dc:subject><dc:subject>Event Sourcing</dc:subject>    
    <content type="html">    &lt;p&gt;I could not attend to this year’s edition that seemed really great with Eric
Evans, Greg Young, Udi Dahan, Ian Cooper and Gojko Adzic.&lt;/p&gt;
&lt;p&gt;The videos from the events should be soon somewhere around &lt;a href="http://skillsmatter.com/event/design-architecture/ddd-exchange-2010/wd-23"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And you can already find transcripts of the talks on Gojko ‘I post faster
than people talk’s blog :&lt;/p&gt;
&lt;p&gt;&lt;a href="http://gojko.net/2010/06/11/eric-evans-domain-driven-design-redefined/" target="_blank"&gt;Eric Evans: Domain driven design redefined&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://gojko.net/2010/06/11/udi-dahan-the-biggest-mistakes-teams-make-when-applying-ddd/" target="_blank"&gt;Udi Dahan: the biggest mistakes teams make when applying
DDD&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://gojko.net/2010/06/11/evolution-of-ddd-cqrs-and-event-sourcing/" target="_blank"&gt;Greg Young :Evolution of DDD: CQRS and Event Sourcing&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;If you also missed it, don’t make the same mistake next year, and &lt;a href="http://skillsmatter.com/event/design-architecture/ddd-exchange-2011/wd-23" target="_blank"&gt;register now for £50.00&lt;/a&gt; (instead of £250.00) until the end
of the week.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=A3UntyhJdEA:vJdiBRqItfs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=A3UntyhJdEA:vJdiBRqItfs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=A3UntyhJdEA:vJdiBRqItfs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=A3UntyhJdEA:vJdiBRqItfs:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=A3UntyhJdEA:vJdiBRqItfs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=A3UntyhJdEA:vJdiBRqItfs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=A3UntyhJdEA:vJdiBRqItfs:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=A3UntyhJdEA:vJdiBRqItfs:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/A3UntyhJdEA" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2010/06/14/DDD-Exchange-2010#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/526729</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2010/06/14/DDD-Exchange-2010</feedburner:origLink></entry>
    
  <entry>
    <title>Event Sourcing and CQRS, Events Deserialization</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/cos0jYx4Rfw/Event-Sourcing-and-CQRS-Events-Deserialization" rel="alternate" type="text/html" title="Event Sourcing and CQRS, Events Deserialization" />
    <id>urn:md5:370b2696a1ad39fb0a07238652438004</id>
    <updated>2010-04-25T22:51:00+02:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>Domain Driven Design</dc:subject>
        <dc:subject>CQRS</dc:subject><dc:subject>Distributed Domain Driven Design</dc:subject><dc:subject>Domain Driven Design</dc:subject><dc:subject>Event Sourcing</dc:subject>    
    <content type="html">    &lt;p&gt;So we have our events serialized in our event store. Deserializing events is
not an issue, until we start to make them evolve and need to manage several
versions.&lt;/p&gt;
&lt;p&gt;Since we never modify what has been log, we’ll have to deal with old
versions anyway.&lt;/p&gt;
&lt;p&gt;A simple way to do it is to &lt;strong&gt;maintain every versions of the
events&lt;/strong&gt; in the projects, and make the aggregate root accept all of
them. But it will soon charge the aggregate root with a lot of code and will
make it bloated rapidly.&lt;/p&gt;
&lt;p&gt;This is why you can usually introduce a &lt;strong&gt;converter&lt;/strong&gt; that will
convert any version of the event to the last one (usually you provide methods
to update to next version, and iterate until last version so that this part of
the code is incremental). This is a convenient way to address the problem, but
you still have classes v1, v2 … vn that you keep in your project only for
versioning purpose even if you don’t use it anymore in your production
code.&lt;/p&gt;
&lt;h3&gt;Events as documents&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/serkel/519485340"&gt;&lt;img style="border-bottom: 0; border-left: 0; margin: 0 0 0 25px; border-top: 0; border-right: 0" title="519485340_1a83117720_o[1]" border="0" alt="519485340_1a83117720_o[1]" align="right" src="http://thinkbeforecoding.com/public/WindowsLiveWriter/EventSourcingandCQRSEventsDeserializatio_13AEE/519485340_1a83117720_o_1__3.jpg" width="184" height="244" /&gt;&lt;/a&gt;It is easy do deserialize an event as an object
&lt;strong&gt;or&lt;/strong&gt; a document, you only need to split two responsibilities in
you deserialization process :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Stream reading&lt;/li&gt;
&lt;li&gt;Object building&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The deserializer will be in charge of reading the data, it reads the bits,
and get the meaning from context, it will tell the Object Builder about objects
types, fields names and value.&lt;/p&gt;
&lt;p&gt;On its side, the ob ject builder will instantiate the objects, set fields
values depending on names.&lt;/p&gt;
&lt;p&gt;You can provides two distinct Object Builders. The strongly typed one will
instantiate concrete .net types and set fields using reflection. The document
builder one, will instantiate objects that will only be property bags.&lt;/p&gt;
&lt;p&gt;When deserializing an event in its last version, you can use directly the
strongly typed one, but when reading an previous version of the event, you can
deserialize it as a document and give it to the converter.&lt;/p&gt;
&lt;p&gt;The converter will then add/remove properties from the document to make it
up to date, and the document will be used to create a concrete .net type of the
last event version.&lt;/p&gt;
&lt;p&gt;Here the process is quite the same, you should provide a document reader
that will use the strongly typed object builder to instantiate the event.&lt;/p&gt;
&lt;p&gt;There’s no need to keep every version of you Event Classes now since you can
manipulate old versions as documents.&lt;/p&gt;
&lt;h3&gt;Using dynamic in C#4&lt;/h3&gt;
&lt;p&gt;Document manipulation can make things a bit messy since it can be hard to
understand the original structure of the object. This is where you can use the
DLR DynamicObject class to make the property bag (the document) a dynamic
object that you’ll be able to use as any standard .net object.&lt;/p&gt;
&lt;p&gt;This way, in the converter you can manipulate old versions of the events as
.net objects without having to keep all those old classes that won’t be used
anymore.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=cos0jYx4Rfw:s1gR0RAON_s:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=cos0jYx4Rfw:s1gR0RAON_s:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=cos0jYx4Rfw:s1gR0RAON_s:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=cos0jYx4Rfw:s1gR0RAON_s:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=cos0jYx4Rfw:s1gR0RAON_s:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=cos0jYx4Rfw:s1gR0RAON_s:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=cos0jYx4Rfw:s1gR0RAON_s:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=cos0jYx4Rfw:s1gR0RAON_s:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/cos0jYx4Rfw" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2010/04/25/Event-Sourcing-and-CQRS-Events-Deserialization#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/511514</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2010/04/25/Event-Sourcing-and-CQRS-Events-Deserialization</feedburner:origLink></entry>
    
  <entry>
    <title>Event Sourcing and CQRS, Bounded Contexts</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/XtrA3WTzzb4/Event-Sourcing-and-CQRS-Bounded-Contexts" rel="alternate" type="text/html" title="Event Sourcing and CQRS, Bounded Contexts" />
    <id>urn:md5:85ee33eb8ae4e47b3485a05e331d45a0</id>
    <updated>2010-04-17T15:21:00+02:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>Domain Driven Design</dc:subject>
        <dc:subject>CQRS</dc:subject><dc:subject>Domain Driven Design</dc:subject><dc:subject>Event Sourcing</dc:subject>    
    <content type="html">    &lt;p&gt;Once again, I prefer a new post that a long comment reply. This one is about
a important concept of Domain Driven Design, Bounded Contexts.&lt;/p&gt;
&lt;p&gt;Hendry Luk asked :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Just 1 question, you represent borrower in events as a simple full-name
string.&lt;br /&gt;
Is there any reason or just for sake of simplicity for example?&lt;br /&gt;
Supposed I'm using borrowerId, how would that work in other BC, say&lt;br /&gt;
LateBookNotifier (let's assume its a separate BC). How does this BC shows
the&lt;br /&gt;
name of the borrower? Does it communicate directly with command BC using
ACL?&lt;br /&gt;
Or does it also subscribe to BorrowerRegistered event as well (hence every
BC&lt;br /&gt;
would have duplicate data of each of the borrowers, just like they do each
of&lt;br /&gt;
the books)?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The short answer is ‘Yes, it was just for sake of simplicity’. In a real
world scenario, borrowers would probably be entities, and thus would have an
identity. I would even probably be an Aggregate Root.&lt;/p&gt;
&lt;p&gt;The Borrower Aggregate Root would encapsulate state needed to perform
commands on this Aggregate.&lt;/p&gt;
&lt;h2&gt;Bounded Contexts Communications&lt;img style="margin: 25px 0 0 15px" title="Books" border="0" alt="Books" align="right" src="http://thinkbeforecoding.com/public/WindowsLiveWriter/EventSourcingandCQRSBoundedContexts_C8DA/Books_3.jpg" width="278" height="228" /&gt;&lt;/h2&gt;
&lt;p&gt;I can see the following contexts here :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Inventory : Manage books availability and state (the book has been damaged,
there a notes written on it etc..)&lt;/li&gt;
&lt;li&gt;Relationships : Manage contact by email, phone with borrowers, and tracks
the care they take to your books, if they return it on schedule.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since we are using CQRS (and even more, Event Sourcing), aggregates in these
context don’t need more state that what’s needed to take decisions,&lt;/p&gt;
&lt;p&gt;So a Book in the Inventory Context will probably not need more that the Id
of the borrower and the date a witch it was borrowed.&lt;br /&gt;
We can then call the ReturnToShelf command on the Book that will publish a
ReturnedLateToShelf { Book : bookId, By : borrowerId, After : 20 days, LateBy :
6 days  }.&lt;/p&gt;
&lt;p&gt;A Handler at the Relationships Boundary will catch the event, and call a
CheckExcuseForLateReturn on the Borrower Aggregate Root (based on its id). The
command will check the borrower’ss record to see if its acceptable. It will
simply publish a LateReturnGentlyAccepted if the borrower is usually in time,
but will publish a KindnessLimitReached in the other case.&lt;br /&gt;
&lt;br /&gt;
Another handler will catch it, and call SendAngryMessage on the Messaging
Service. The role of the Messaging Service is to tweet borrowers to let them
know they should not forget to return your books. How does this service know
the twitter account of the borrower ? When the handler (the one that call
SendAngryMessage) catches a BorrowerRegistered event or a
BorrowerTwitterAccountChanged message, it says so to the service that can
maintain a list of accounts in any desired storage (SLQ, NoSql, in memory.. ?).
The SendAngryMessage can now tweet ‘Hey you filthy @borrower, you better return
my book today or I shall share all the pics from your last party…’&lt;/p&gt;
&lt;p&gt;Done.&lt;/p&gt;
&lt;h2&gt;Where does data live ?&lt;/h2&gt;
&lt;p&gt;There’s usually a huge concern about data duplication in all contexts. Is
the info duplicated in so many places ?&lt;/p&gt;
&lt;p&gt;There will be two main places :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Persistent View Model used to see and edit borrower’s details&lt;/li&gt;
&lt;li&gt;The Persistent View Model used by the messaging service to Query borrower’s
twitter accounts. Here, no other borrower’s data is needed except its id and
account name.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Borrower Aggregate Root and Book Aggregate Root in the two main Domain
Bounded Contexts will not need to keep track of this kind of data. They won’t
need it in their decision process.&lt;/p&gt;
&lt;p&gt;If you pursue this idea, to answer further to Leonardo, you’ll notice that
strings will probably never been used as state inside Domain Bounded Context.
They can appear as identity key, or just pass through a command and be
republished in the following event. But since strings are rarely – if never – a
good way to represent information on which you’ll have to take a decision, it
should almost never be stored in an aggregate root current state. This is
another reason why most domain models can fit in memory, because names,
descriptions and other documents usually represent the biggest part of the data
in a system, the remaining data is usually small. These documents and names are
useless to run domain  internal logic (except validation rules, but not
state change rules) so they can simply be logged in events and persisted in the
Query’s View Models. Only state needed to take state change decisions will stay
in memory.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=XtrA3WTzzb4:skJdnAUKMDY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=XtrA3WTzzb4:skJdnAUKMDY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=XtrA3WTzzb4:skJdnAUKMDY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=XtrA3WTzzb4:skJdnAUKMDY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=XtrA3WTzzb4:skJdnAUKMDY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=XtrA3WTzzb4:skJdnAUKMDY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=XtrA3WTzzb4:skJdnAUKMDY:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=XtrA3WTzzb4:skJdnAUKMDY:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/XtrA3WTzzb4" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2010/04/17/Event-Sourcing-and-CQRS-Bounded-Contexts#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/509715</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2010/04/17/Event-Sourcing-and-CQRS-Bounded-Contexts</feedburner:origLink></entry>
    
  <entry>
    <title>Event Sourcing and CQRS, Snapshots !</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/8I6uO6EcmkU/Event-Sourcing-and-CQRS-Snapshots" rel="alternate" type="text/html" title="Event Sourcing and CQRS, Snapshots !" />
    <id>urn:md5:efe26f1f63b0b2be0bc518cb35f4f5b2</id>
    <updated>2010-02-25T10:38:00+01:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>Domain Driven Design</dc:subject>
        <dc:subject>CQRS</dc:subject><dc:subject>Distributed Domain Driven Design</dc:subject><dc:subject>Domain Driven Design</dc:subject>    
    <content type="html">    &lt;p&gt;Leonardo had a question about reloading huge amounts of events.&lt;/p&gt;
&lt;p&gt;It’s true that some Aggregate Roots have very long lifetimes with lots of
events, and it can become a problem.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;There are two things involved to resolve this problem :&lt;/p&gt;
&lt;h3&gt;Snapshots&lt;/h3&gt;
&lt;p&gt;Ok, the philosophy of event sourcing is to store changes instead of state,
but we’ll still need state in our Aggregate Roots, and getting it from scratch
can be long.&lt;/p&gt;
&lt;p&gt;Take a snapshot every n events (you’ll see that n can be quite high), and
store it alongside events, with the version of the aggregate root.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;To reload the Aggregate Root, simply find the snapshot, give it to the
Aggregate root, the replay events that happened after the snapshot.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;You only need the last snapshot for each Aggregate Root, no need to log all
passed snapshots.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;When you want to change stored state in an Aggregate Root, you won’t be able
to used last snapshot since it will not contains expected state. But you can
still replay events from scratch when it happens, so you have no loss, and
simply take a new snapshot with the new state.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;In memory domain&lt;/h3&gt;
&lt;p&gt;Usually with an ORM, you reload entities from the storage on every unit of
work.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;But in the case of Event Sourcing, your Aggregate Roots only need to retain
state that will be used to take business decisions. You’ll never query state
from Aggregate Roots. A large part of the entity state and especially the part
that has the biggest memory footprint is usually stored only for queries, like
names, descriptions and things like that.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;In an Aggregate Root in an Event Sourcing environment, a name or description
can simply be checked for validity, put in an event, but don’t need to be
kipped in the in memory entity state – the Aggregate Root fields.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;You’ll notice that your big domain state can fit in memory once you’ve
trimmed it this way.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Now that your model is in memory, no need to reload every events on each
unit of work. It happens only once when the Aggregate Root is needed the first
time.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Well see soon how you can use this to make your event serialization even
faster to have very high business peak throughput.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=8I6uO6EcmkU:kWbR97fIfUs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=8I6uO6EcmkU:kWbR97fIfUs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=8I6uO6EcmkU:kWbR97fIfUs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=8I6uO6EcmkU:kWbR97fIfUs:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=8I6uO6EcmkU:kWbR97fIfUs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=8I6uO6EcmkU:kWbR97fIfUs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=8I6uO6EcmkU:kWbR97fIfUs:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=8I6uO6EcmkU:kWbR97fIfUs:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/8I6uO6EcmkU" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2010/02/25/Event-Sourcing-and-CQRS-Snapshots#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/489754</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2010/02/25/Event-Sourcing-and-CQRS-Snapshots</feedburner:origLink></entry>
    
  <entry>
    <title>Business Errors are Just Ordinary Events</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/oAjAObrAsG0/Business-Errors-are-Just-Ordinary-Events" rel="alternate" type="text/html" title="Business Errors are Just Ordinary Events" />
    <id>urn:md5:145125b298e5943f8397dad3338e6532</id>
    <updated>2009-12-10T14:31:00+01:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>Domain Driven Design</dc:subject>
            
    <content type="html">    &lt;p&gt;Error handling has always been something quite difficult to grasp in
software design and still is.&lt;/p&gt;
&lt;p&gt;Exceptions are now widespread in languages, and it helps a lot to manage
corner case where something fails badly.&lt;/p&gt;
&lt;p&gt;But should we use Exceptions to manage business errors ?&lt;/p&gt;
&lt;h2&gt;The business errors&lt;/h2&gt;
&lt;p&gt;What do we call business errors actually ?&lt;/p&gt;
&lt;h3&gt;Broken Invariants&lt;/h3&gt;
&lt;p&gt;What if an invariance rule is broken ?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The situation should never happen&lt;/strong&gt; : There is a bug. A bug
is not a business error, correct it and deploy.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The situation can happens sometimes&lt;/strong&gt; : This is not an
invariant, but a rare state. It should be handled as any other state
change.&lt;/p&gt;
&lt;h3&gt;Invalid commands&lt;/h3&gt;
&lt;p&gt;What if we receive an invalid command ?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The command data is meaningless&lt;/strong&gt; : There’s a bug, you should
always validate that command data is not just garbage.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The command leads to an invalid state&lt;/strong&gt; : The user
nonetheless requested to perform the command.&lt;/p&gt;
&lt;p&gt;In this case the event will be ‘the request was rejected’. The event can be
handled by sending an email back to the customer, or a support request can be
started so that the support can call the customer and manage the problem.
&lt;em&gt;All this is part of the business process anyway&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;Corner cases create business opportunities&lt;/h2&gt;
&lt;p&gt;I can often see discussions around account validation for credit, to make
the transaction fail when your account goes below zero.&lt;/p&gt;
&lt;p&gt;But it’s not what’s happening in real life. Transaction is accepted, then
the bank charges you because your account is in the red zone.&lt;/p&gt;
&lt;p&gt;I’m currently working in the hotel business. When a booking is received
and  there’s no room left, should I reject the booking ? Another client
can cancel soon, or I can move the customer to another hotel nearby, but just
saying ‘there’s no room left’ is not a good business answer ! Overbooking
management has even become a strategic practice in the business.&lt;/p&gt;
&lt;p&gt;To fully manage your customers you should embrace the whole business
lifecycle in your system. This includes support and corner case management.
Part of it will be done by hand, other part automatically, but you should not
just report an exception is a trace log.&lt;/p&gt;
&lt;p&gt;These critical situations are usually the one in which you customer needs
you more than in any other case, you should design your fault handling strategy
with care and make it a full concern of you business.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=oAjAObrAsG0:4ioDweNRu3o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=oAjAObrAsG0:4ioDweNRu3o:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=oAjAObrAsG0:4ioDweNRu3o:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=oAjAObrAsG0:4ioDweNRu3o:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=oAjAObrAsG0:4ioDweNRu3o:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=oAjAObrAsG0:4ioDweNRu3o:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=oAjAObrAsG0:4ioDweNRu3o:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=oAjAObrAsG0:4ioDweNRu3o:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/oAjAObrAsG0" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2009/12/10/Business-Errors-are-Just-Ordinary-Events#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/466830</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2009/12/10/Business-Errors-are-Just-Ordinary-Events</feedburner:origLink></entry>
    
  <entry>
    <title>Udi Dahan's post on CQRS</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/PXxyk0b37xw/Udi-Dahan-post-on-CQRS" rel="alternate" type="text/html" title="Udi Dahan's post on CQRS" />
    <id>urn:md5:b62067d37689e6893975eff0823421b5</id>
    <updated>2009-12-10T10:15:00+01:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>Domain Driven Design</dc:subject>
            
    <content type="html">    &lt;p&gt;Udi Dahan wrote a new post on CQRS today : &lt;a href="http://www.udidahan.com/2009/12/09/clarified-cqrs/" target="_blank"&gt;Clarified
CQRS&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It is essentially the content of the presentation he gave here in Paris and
in other places.&lt;/p&gt;
&lt;p&gt;You should read it I you want to understand the deep reasons to use CQRS and
see how to change your mind to use it.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=PXxyk0b37xw:hG64q76qPuU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=PXxyk0b37xw:hG64q76qPuU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=PXxyk0b37xw:hG64q76qPuU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=PXxyk0b37xw:hG64q76qPuU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=PXxyk0b37xw:hG64q76qPuU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=PXxyk0b37xw:hG64q76qPuU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=PXxyk0b37xw:hG64q76qPuU:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=PXxyk0b37xw:hG64q76qPuU:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/PXxyk0b37xw" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2009/12/10/Udi-Dahan-post-on-CQRS#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/466789</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2009/12/10/Udi-Dahan-post-on-CQRS</feedburner:origLink></entry>
    
  <entry>
    <title>Udi Dahan talks on CQRS in Paris</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/obzDZMemFIo/Udi-Dahan-talks-on-CQRS-in-Paris" rel="alternate" type="text/html" title="Udi Dahan talks on CQRS in Paris" />
    <id>urn:md5:4d9b270c91aa510fb7d678a4b83b8eca</id>
    <updated>2009-11-17T16:37:00+01:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>Domain Driven Design</dc:subject>
            
    <content type="html">    &lt;p&gt;&lt;a href="http://www.udidahan.com/" target="_blank"&gt;Udi Dahan&lt;/a&gt; gave a very
good talk yesterday evening at Zenika, there was only few attendees… perhaps
because it was on a Monday evening. Whatever, there was barely not enough place
already in the Italian restaurant where we moved after.&lt;/p&gt;
&lt;p&gt;I won’t make a full report, just talk about some interesting points.&lt;/p&gt;
&lt;p&gt;First of all, the session focused mainly on why you should do CQRS and not
how. Second point, the talk was not about event sourcing, but you already now
that you can do CQRS without event sourcing.&lt;/p&gt;
&lt;h2&gt;Something we should accept : Stale Data&lt;/h2&gt;
&lt;p&gt;The paradigm of usual architecture’s best practice has a serious flow : when
you show data to your users, it’s already stale.&lt;/p&gt;
&lt;p&gt;Is it important ? Yes.&lt;/p&gt;
&lt;p&gt;Is it a problem ? Not really.&lt;/p&gt;
&lt;p&gt;The world have worked with stale data for years, and it was handled rather
gracefully until now. Computers have reduced the time span, but when the data
appear on the screen, it’s stale.&lt;/p&gt;
&lt;p&gt;Tel it to your users, they will accept it. Find with them what is
acceptable. 1 second, 10 seconds, 1 minute, 1 hour, 1 day ? The users are used
to it in there own business. Do it too.&lt;/p&gt;
&lt;h2&gt;Queries&lt;/h2&gt;
&lt;p&gt;What’s the purpose of queries ? To show data. Not objects.&lt;/p&gt;
&lt;p&gt;So why should the data from the database come across 5 layers through 3
model transformations ? It’s a bit overkill to display data.&lt;/p&gt;
&lt;p&gt;Why not just this : The UI read data from the database and displays it ?&lt;/p&gt;
&lt;p&gt;No DTOs, no ORM, not business rules executed on each query.&lt;/p&gt;
&lt;p&gt;You simply define a &lt;strong&gt;Persistent ViewModel&lt;/strong&gt; (thank’s Udi, I
like this description of the Q side), and display it directly to screen. It
should be as simple as one database table per UI view.&lt;/p&gt;
&lt;p&gt;Of course you need a way to keep the Persistent ViewModel up to date, but
we’ll see that later.&lt;/p&gt;
&lt;h2&gt;Commands&lt;/h2&gt;
&lt;p&gt;On the other side, there are commands.&lt;/p&gt;
&lt;p&gt;It should be done in 3 phases :&lt;/p&gt;
&lt;h3&gt;Validation&lt;/h3&gt;
&lt;p&gt;Is the input potentially good ? Structured correctly, no missing field,
everything fit in ranges ?&lt;/p&gt;
&lt;p&gt;This can be done without knowing current state, and be done outside of
entities command handling.&lt;/p&gt;
&lt;h3&gt;Rules&lt;/h3&gt;
&lt;p&gt;Should we do this ?&lt;/p&gt;
&lt;p&gt;Here, the decision is taken using current state.&lt;/p&gt;
&lt;p&gt;It leads to a discussion about UI design. In order to handle the user
command as well as you can, you have to capture the user intent in the
command.&lt;/p&gt;
&lt;p&gt;In CRUD applications, the new data is sent by the UI layer. You have to
extract the user intent from that data to know if you can process the data.&lt;/p&gt;
&lt;p&gt;There is a huge difference between UserMovesToNewAddress and
CorrectTheMisspellingInUserAddress from a business point, but in a CRUD
application you would probably end with the same Update data…&lt;/p&gt;
&lt;h3&gt;State change&lt;/h3&gt;
&lt;p&gt;What’s the new state ?&lt;/p&gt;
&lt;p&gt;It’s the easy part once the rules are applied.&lt;/p&gt;
&lt;h2&gt;Domain Model&lt;/h2&gt;
&lt;h3&gt;What aren’t they for ?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Validation&lt;/strong&gt; : commands are validated before the model is
called. Do not bloat your domain model with this.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Queries&lt;/strong&gt; : entity relationships for reading are unnecessary.
You can do eager loading on your Aggregate Roots safely, they’ll never be used
for queries that need only partial information.&lt;/p&gt;
&lt;h3&gt;What are they for ?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Answer to the question&lt;/strong&gt; : should we do what this valid
command is asking ?&lt;/p&gt;
&lt;p&gt;If the answer is yes, &lt;strong&gt;change the state&lt;/strong&gt; !&lt;/p&gt;
&lt;h2&gt;Maintain the query model up to date&lt;/h2&gt;
&lt;p&gt;There are two main ways to maintain query model up to date.&lt;/p&gt;
&lt;p&gt;You can use something like views or ETL to transform data from the domain
data to the shape required by the query side.&lt;/p&gt;
&lt;p&gt;If you prefer, or when your domain persistence is not compatible with this
option (OODB, Event Storage..), you can publish events from you command side,
and provides handler’s on the query side that will maintain the views state in
the relational database (or a cube… or whatever). A denormalization will happen
here.&lt;/p&gt;
&lt;h2&gt;What do we gain from this ?&lt;/h2&gt;
&lt;h3&gt;Asynchronous model&lt;/h3&gt;
&lt;p&gt;The model is deeply asynchronous, it’s not a matter of tweaking things with
threads. It’s asynchronous from the ground up, at domain level.&lt;/p&gt;
&lt;p&gt;Your user sends a command, and your design is good if you can answer :
“thank you, we will come back to you soon…”. Take the time needed to fulfill
your user wish, he will be happy !&lt;/p&gt;
&lt;h3&gt;Scalability&lt;/h3&gt;
&lt;p&gt;By relaxing the rules, the system becomes more scalable.&lt;/p&gt;
&lt;h3&gt;Domain persistence choice&lt;/h3&gt;
&lt;p&gt;The domain is accessed only to process rules and state changes. There is no
need to join tables, filter rows. So you can easily use an non relational
database.&lt;/p&gt;
&lt;p&gt;Possible options are a OODB or an Event Storage (for event sourcing).&lt;/p&gt;
&lt;p&gt;You can still use a RDBMS with or without an ORM if you’re more familiar
with these technologies.&lt;/p&gt;
&lt;p&gt;But the persistence mechanism becomes an implementation detail from from
Command side that will not interfere with your queries.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Ooops, I said it was not a complete report… but it actually is. Every point
was interesting ?&lt;/p&gt;
&lt;p&gt;After the talk we had a discussion about forecasting and other interesting
subjects. Perhaps more on this later.&lt;/p&gt;
&lt;p&gt;There was a video camera in the room, so I think the guys from Zenika will
try to put it on the internet when they have time. I’ll add the link when
available.&lt;/p&gt;
&lt;p&gt;If you was here and have a picture of the event, I would be glad to put it
in the blog :D&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=obzDZMemFIo:U5nXozVLcMU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=obzDZMemFIo:U5nXozVLcMU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=obzDZMemFIo:U5nXozVLcMU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=obzDZMemFIo:U5nXozVLcMU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=obzDZMemFIo:U5nXozVLcMU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=obzDZMemFIo:U5nXozVLcMU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=obzDZMemFIo:U5nXozVLcMU:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=obzDZMemFIo:U5nXozVLcMU:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/obzDZMemFIo" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2009/11/17/Udi-Dahan-talks-on-CQRS-in-Paris#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/460508</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2009/11/17/Udi-Dahan-talks-on-CQRS-in-Paris</feedburner:origLink></entry>
    
  <entry>
    <title>Udi Dahan talks on CQRS at Zenika</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/P_DOL6L5T5s/Udi-Dahan-talks-on-CQRS-at-Zenika" rel="alternate" type="text/html" title="Udi Dahan talks on CQRS at Zenika" />
    <id>urn:md5:af932606313d2692d12af103cea76e54</id>
    <updated>2009-11-16T11:08:00+01:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>Domain Driven Design</dc:subject>
        <dc:subject>CQRS</dc:subject><dc:subject>Distributed Domain Driven Design</dc:subject><dc:subject>Domain Driven Design</dc:subject>    
    <content type="html">    &lt;p&gt;I’ll be at &lt;a href="http://www.udidahan.com/" target="_blank"&gt;Udi
Dahan&lt;/a&gt;’s talk this evening (19h) at Zenika in Paris.&lt;/p&gt;
&lt;p&gt;Tell me if you’re planning to be there too !&lt;/p&gt;
&lt;p&gt;I’ll surely post about it in the following days.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=P_DOL6L5T5s:BLCIgbDO2z4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=P_DOL6L5T5s:BLCIgbDO2z4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=P_DOL6L5T5s:BLCIgbDO2z4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=P_DOL6L5T5s:BLCIgbDO2z4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=P_DOL6L5T5s:BLCIgbDO2z4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=P_DOL6L5T5s:BLCIgbDO2z4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=P_DOL6L5T5s:BLCIgbDO2z4:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=P_DOL6L5T5s:BLCIgbDO2z4:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/P_DOL6L5T5s" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2009/11/16/Udi-Dahan-talks-on-CQRS-at-Zenika#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/460191</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2009/11/16/Udi-Dahan-talks-on-CQRS-at-Zenika</feedburner:origLink></entry>
    
  <entry>
    <title>Event Sourcing and CQRS, Serialization</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/eqhi1doOIUY/Event-Sourcing-and-CQRS-Serialization" rel="alternate" type="text/html" title="Event Sourcing and CQRS, Serialization" />
    <id>urn:md5:c55a1bc2959d5eaa2c2ca830df99f2d9</id>
    <updated>2009-11-05T14:00:00+01:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>Domain Driven Design</dc:subject>
        <dc:subject>CQRS</dc:subject><dc:subject>Design</dc:subject><dc:subject>Distributed Domain Driven Design</dc:subject><dc:subject>Domain Driven Design</dc:subject>    
    <content type="html">    &lt;p&gt;Be sure to read the three preceding parts of the series:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://thinkbeforecoding.com/post/2009/10/30/Event-Sourcing-and-CQRS-Now" target="_blank"&gt;Event Sourcing and CQRS, Now !&lt;/a&gt;  &lt;br /&gt;
&lt;a href="http://thinkbeforecoding.com/post/2009/11/02/Event-Sourcing-and-CQRS-Lets-use-it" target="_blank"&gt;Event Sourcing and CQRS, Let’s use it&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://thinkbeforecoding.com/post/2009/11/03/Event-Sourcing-and-CQRS-Dispatch-options" target="_blank"&gt;Event Sourcing and CQRS; Dispatch-options&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Today, we’ll study to a required part of the event storage :
Serialization/Deserialization&lt;/p&gt;
&lt;h2&gt;The easy way&lt;/h2&gt;
&lt;p&gt;The .Net framework as several serialization technologies that can be used
here, Binary serialization, XML serialization or even DataContract
serialization introduced with WCF.&lt;/p&gt;
&lt;h2&gt;The penalty&lt;/h2&gt;
&lt;p&gt;The particularity of Event Sourcing is that we will never delete or update
stored events. They’ll be logged, insert only, once and forever.&lt;/p&gt;
&lt;p&gt;So the log grows. grows. grows.&lt;/p&gt;
&lt;p&gt;Event storage size will influence greatly the growth rate of the log.&lt;/p&gt;
&lt;h3&gt;Xml Serialization&lt;/h3&gt;
&lt;p&gt;If your system processes frequently lots of events, forget about XML. Far to
verbose, you’ll pay the &lt;a href="http://www.codinghorror.com/blog/archives/001114.html" target="_blank"&gt;Angle
Bracket Tax&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Binary Serialization&lt;/h3&gt;
&lt;p&gt;But the binary serialization still cost much, even if compact, it will
contain type names and field names…&lt;/p&gt;
&lt;h3&gt;Raw Serialization&lt;/h3&gt;
&lt;p&gt;You could write serialization/deserialization code into your type.&lt;/p&gt;
&lt;p&gt;The type can chose a format, so no extra type/field name is needed. This
kind of serialization is very compact – it contains only required bits – but
you cannot read data back without the deserialization code.&lt;/p&gt;
&lt;p&gt;It can be ok if you plan to have a definite small number of well documented
events. Unmanageable if your event type count will grow with time and
versions.&lt;/p&gt;
&lt;h2&gt;Avoid it&lt;/h2&gt;
&lt;p&gt;Let’s consider how data are stored in a database.&lt;/p&gt;
&lt;p&gt;A database contains tables. Tables have a schema. When storing a row, no
need to repeat column names on each cell. The data layout is defined by the
table schema and will be the same on each row.&lt;/p&gt;
&lt;p&gt;We cannot do the same since events have different schemas, but we work with
a limited set of events that will occur many times.&lt;/p&gt;
&lt;h2&gt;Split schema and data&lt;/h2&gt;
&lt;p&gt;We can thus store schemas aside, and specify the row data schema on each
row. The event data will the be stored as raw bits corresponding to specified
schema.&lt;/p&gt;
&lt;p&gt;This way you can design tools to explore your log file with complete event
representation without needing the original event class, and you got a very
compact serialization. Have your cake and eat it too !&lt;/p&gt;
&lt;p&gt;Stay tuned, the code comes tomorrow…&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=eqhi1doOIUY:kLKgK1oQQj0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=eqhi1doOIUY:kLKgK1oQQj0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=eqhi1doOIUY:kLKgK1oQQj0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=eqhi1doOIUY:kLKgK1oQQj0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=eqhi1doOIUY:kLKgK1oQQj0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=eqhi1doOIUY:kLKgK1oQQj0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=eqhi1doOIUY:kLKgK1oQQj0:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=eqhi1doOIUY:kLKgK1oQQj0:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/eqhi1doOIUY" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2009/11/05/Event-Sourcing-and-CQRS-Serialization#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/457791</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2009/11/05/Event-Sourcing-and-CQRS-Serialization</feedburner:origLink></entry>
    
  <entry>
    <title>Event Sourcing and CQRS, Dispatch options.</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/hzMSb2CMLmA/Event-Sourcing-and-CQRS-Dispatch-options" rel="alternate" type="text/html" title="Event Sourcing and CQRS, Dispatch options." />
    <id>urn:md5:07e43fc62650cd848784b9a430a56c74</id>
    <updated>2009-11-03T15:41:00+01:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>Domain Driven Design</dc:subject>
        <dc:subject>CQRS</dc:subject><dc:subject>Design</dc:subject><dc:subject>Distributed Domain Driven Design</dc:subject><dc:subject>Domain Driven Design</dc:subject>    
    <content type="html">    &lt;p&gt;As seen in &lt;a href="http://thinkbeforecoding.com/post/2009/11/02/Event-Sourcing-and-CQRS%2C-Letrsquo%3Bs-use-it." target="_blank"&gt;previous post&lt;/a&gt;, I used dynamic to replay events.&lt;/p&gt;
&lt;p&gt;The main reason to use it was to avoid long code using reflection in the
infrastructure that would have made it hard to read.&lt;/p&gt;
&lt;p&gt;I’ll show several ways to do this dispatch with pros and cons in each
cases.&lt;/p&gt;
&lt;h2&gt;Dynamic&lt;/h2&gt;
&lt;p&gt;The proposed solution was using dynamic.&lt;/p&gt;
&lt;p&gt;+ Pros : there is no reflection code involved, code is very simple.&lt;br /&gt;
- Cons : all state change (Apply) methods must have the same name.&lt;/p&gt;
&lt;p&gt;I made no performance test, so I cannot judge if perf is better or not. It
seems that the DLR has a rather good cache when the same type is encountered
several time, but only measures can tell.&lt;/p&gt;
&lt;h2&gt;Handlers registration&lt;/h2&gt;
&lt;p&gt;This is the current implementation in &lt;a href="http://github.com/MarkNijhof/Fohjin/blob/9ae1f925c4a71aaaa7d2f1a5c24dcb63aabe7b54/Fohjin.DDD/Fohjin.DDD.Domain/BaseAggregateRoot.cs" target="_blank"&gt;Mark Nijhof’s sample&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The base class maintains a dictionary of Type/Action&amp;lt;T&amp;gt; association to
dispatch events based on type.&lt;/p&gt;
&lt;p&gt;Since an Action&amp;lt;T&amp;gt; delegate must have a target instance, the delegate
must be constructed from within the instance, in the .ctor.&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;AggregateRoot&lt;/span&gt;&amp;lt;TId&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Type&lt;/span&gt;,
&lt;span style="COLOR: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt; handlers =&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
             
&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Type&lt;/span&gt;,
&lt;span style="COLOR: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
Register&amp;lt;T&amp;gt;(&lt;span style="COLOR: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;T&amp;gt;
handler)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
handlers.Add(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(T),e =&amp;gt;
handler((T)e));&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
Replay(&lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt; events)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; @event
&lt;span style="COLOR: blue"&gt;in&lt;/span&gt; events)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
handlers[@event.GetType()](@event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: green"&gt;// rest of the aggregate root class&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Here is code that use it :&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Book&lt;/span&gt;
: &lt;span style="COLOR: #2b91af"&gt;AggregateRoot&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt;&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; id;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; Book(&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt;
id,&lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt; events) : &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;(id)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
Replay(events);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; Book(&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt;
id,&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; title, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; isbn) : &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;(id)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; @event = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;BookRegistered&lt;/span&gt;(id, title, isbn);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
OnBookRegistered(@event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
Append(@event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; Book(&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt;
id)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.id = id;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
Register&amp;lt;&lt;span style="COLOR: #2b91af"&gt;BookRegistered&lt;/span&gt;&amp;gt;(OnBookRegistered);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
Register&amp;lt;&lt;span style="COLOR: #2b91af"&gt;BookLent&lt;/span&gt;&amp;gt;(OnBookLent);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
Register&amp;lt;&lt;span style="COLOR: #2b91af"&gt;BookReturned&lt;/span&gt;&amp;gt;(OnBookReturned);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
OnBookRegistered(&lt;span style="COLOR: #2b91af"&gt;BookRegistered&lt;/span&gt; @event) {
&lt;span style="COLOR: green"&gt;/**/&lt;/span&gt; }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
OnBookLent(&lt;span style="COLOR: #2b91af"&gt;BookLent&lt;/span&gt; @event) { &lt;span style="COLOR: green"&gt;/**/&lt;/span&gt; }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
OnBookReturned(&lt;span style="COLOR: #2b91af"&gt;BookReturned&lt;/span&gt; @event) {
&lt;span style="COLOR: green"&gt;/**/&lt;/span&gt; }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;+Pros : Still no reflection,&lt;br /&gt;
            Meaningful
method names&lt;br /&gt;
-Cons : Additional plumbing code, &lt;br /&gt;
            Private
constructor to avoid repetition&lt;br /&gt;
            Registration
occurs at each instantiation&lt;/p&gt;
&lt;h2&gt;Convention Based Method Naming&lt;/h2&gt;
&lt;p&gt;This is the way &lt;a href="http://tech.groups.yahoo.com/group/domaindrivendesign/message/15743" target="_blank"&gt;advocated by Greg Young&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If your event is called BookRegistered, assume the method will be called
OnBookRegistered, and find it by reflection. You can implement a cache at class
level to avoid reflection on each dispatch.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;AggregateRoot&lt;/span&gt;&amp;lt;TId&amp;gt; : &lt;span style="COLOR: #2b91af"&gt;IAggregateRoot&lt;/span&gt;&amp;lt;TId&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Type&lt;/span&gt;,
&lt;span style="COLOR: #2b91af"&gt;IEventDispatcher&lt;/span&gt;&amp;gt; Handlers =&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
              
&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Type&lt;/span&gt;,
&lt;span style="COLOR: #2b91af"&gt;IEventDispatcher&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt; &lt;span style="COLOR: blue"&gt;object&lt;/span&gt; HandlersLock = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
Replay(&lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt; events)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; dispatcher = GetDispatcher();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
dispatcher.Dispatch(&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;, @events);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IEventDispatcher&lt;/span&gt; GetDispatcher()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: #2b91af"&gt;IEventDispatcher&lt;/span&gt; handlers;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; type = GetType();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;lock&lt;/span&gt; (HandlersLock)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (!Handlers.TryGetValue(type, &lt;span style="COLOR: blue"&gt;out&lt;/span&gt; handlers))&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
{&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                   
handlers = &lt;span style="COLOR: #2b91af"&gt;EventDispatcher&lt;/span&gt;.Create(type);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                   
Handlers.Add(type, handlers);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
}&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; handlers;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        ... rest of the
code here&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The dispatcher code :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: blue"&gt;interface&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;IEventDispatcher&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Dispatch(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;
target, &lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt;events);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;EventDispatcher&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="COLOR: #2b91af"&gt;IEventDispatcher&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Type&lt;/span&gt;, &lt;span style="COLOR: #2b91af"&gt;IEventHandler&lt;/span&gt;&amp;lt;T&amp;gt;&amp;gt; handlers;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; EventDispatcher()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; h = &lt;span style="COLOR: blue"&gt;from&lt;/span&gt; m
&lt;span style="COLOR: blue"&gt;in&lt;/span&gt; &lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(T)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
             
.GetMethods(&lt;span style="COLOR: #2b91af"&gt;BindingFlags&lt;/span&gt;.Instance |
&lt;span style="COLOR: #2b91af"&gt;BindingFlags&lt;/span&gt;.NonPublic)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                   
&lt;span style="COLOR: blue"&gt;let&lt;/span&gt; parameters = m.GetParameters()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                   
&lt;span style="COLOR: blue"&gt;where&lt;/span&gt; parameters.Length ==1&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                   
&amp;amp;&amp;amp; m.Name == &lt;span style="COLOR: #a31515"&gt;&amp;quot;On&amp;quot;&lt;/span&gt; +
parameters[0].ParameterType.Name&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                   
&lt;span style="COLOR: blue"&gt;select&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;EventHandler&lt;/span&gt;.Create&amp;lt;T&amp;gt;(m);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            handlers =
h.ToDictionary(i =&amp;gt; i.EventType);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
Dispatch(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; target, &lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt; events)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; typedTarget = (T)target;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; @event
&lt;span style="COLOR: blue"&gt;in&lt;/span&gt; events)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; handler = handlers[@event.GetType()];&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
handler.Call(typedTarget, @event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;EventDispatcher&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;IEventDispatcher&lt;/span&gt; Create(&lt;span style="COLOR: #2b91af"&gt;Type&lt;/span&gt; type)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; (&lt;span style="COLOR: #2b91af"&gt;IEventDispatcher&lt;/span&gt;)&lt;span style="COLOR: #2b91af"&gt;Activator&lt;/span&gt;.CreateInstance(&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
              
&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: #2b91af"&gt;EventDispatcher&lt;/span&gt;&amp;lt;&amp;gt;).MakeGenericType(type));&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;and the event handler :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: blue"&gt;interface&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;IEventHandler&lt;/span&gt;&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Call(T target, &lt;span style="COLOR: blue"&gt;object&lt;/span&gt; argument);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: #2b91af"&gt;Type&lt;/span&gt; EventType { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;;
}&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;EventHandler&lt;/span&gt;&amp;lt;TEntity, TEvent&amp;gt; :
&lt;span style="COLOR: #2b91af"&gt;IEventHandler&lt;/span&gt;&amp;lt;TEntity&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;TEntity, TEvent&amp;gt; handler;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; EventHandler(&lt;span style="COLOR: #2b91af"&gt;MethodInfo&lt;/span&gt; methodInfo)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            handler =
(&lt;span style="COLOR: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;TEntity, TEvent&amp;gt;)&lt;span style="COLOR: #2b91af"&gt;Delegate&lt;/span&gt;.CreateDelegate(&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                 
&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;TEntity, TEvent&amp;gt;), methodInfo,
&lt;span style="COLOR: blue"&gt;true&lt;/span&gt;);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Call(TEntity
target, &lt;span style="COLOR: blue"&gt;object&lt;/span&gt; argument)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
handler(target, (TEvent)argument);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Type&lt;/span&gt;
EventType&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(TEvent); }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;EventHandler&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;IEventHandler&lt;/span&gt;&amp;lt;T&amp;gt;
Create&amp;lt;T&amp;gt;(&lt;span style="COLOR: #2b91af"&gt;MethodInfo&lt;/span&gt; methodInfo)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; eventType =
methodInfo.GetParameters()[0].ParameterType;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; (&lt;span style="COLOR: #2b91af"&gt;IEventHandler&lt;/span&gt;&amp;lt;T&amp;gt;)&lt;span style="COLOR: #2b91af"&gt;Activator&lt;/span&gt;.CreateInstance(&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                 
&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: #2b91af"&gt;EventHandler&lt;/span&gt;&amp;lt;,&amp;gt;)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                 
.MakeGenericType(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(T), eventType),&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                 
methodInfo&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                 
);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The trick here is to create a static delegate with two parameters from an
instance method info that take one parameter (and one implicit this
target).&lt;/p&gt;
&lt;p&gt;This way, the delegate is not tied to a specific instance and can be used on
any target.&lt;/p&gt;
&lt;p&gt;As you can see, this option requires more code ! I did not want to start
with that.&lt;/p&gt;
&lt;p&gt;+Pros : Convention base names mean no manual mapping, mapping is
implicit&lt;br /&gt;
            Binding is
made a class level instead of instance level&lt;/p&gt;
&lt;p&gt;-Cons : Only unit tests can tell when you mess with names&lt;br /&gt;
            Not immune
to event name change, should have good unit tests !&lt;/p&gt;
&lt;h2&gt;Apply then Append&lt;/h2&gt;
&lt;p&gt;I also had a remark that if I forget Append after Apply, I’ll get in
trouble.&lt;/p&gt;
&lt;p&gt;In Handler Registration option and Convention base method naming, the
dispatch can be done by the base class, so I could tell the base class to
dispatch then Append then event to UncommittedEvents.&lt;/p&gt;
&lt;p&gt;This way you end with something like :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; @event = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt;
BookLent(&lt;span style="COLOR: green"&gt;/**/&lt;/span&gt;);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
Play(@event);&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;where play dispatches the event to the right method and appends.&lt;/p&gt;
&lt;p&gt;This way you cannot forget.&lt;/p&gt;
&lt;p&gt;My problem with this, especially in the Convention base method naming
scenario is that nobody references the event application methods anymore.
Resharper will report them as unused methods, and you won’t know unless you run
unit tests.&lt;/p&gt;
&lt;p&gt;Moreover, you pay the cost of a dynamic dispatch when you know your event
type.&lt;/p&gt;
&lt;p&gt;Perhaps something like this could be better :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; @event = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt;
BookLent(&lt;span style="COLOR: green"&gt;/**/&lt;/span&gt;);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
Play(@event).With(OnBookLent);&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;the implementation is not very complicated :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;AggregateRoot&lt;/span&gt;&amp;lt;TId&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;UncommittedEvents&lt;/span&gt; uncommittedEents;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;EventPlayer&lt;/span&gt;&amp;lt;TEvent&amp;gt; Play&amp;lt;TEvent&amp;gt;(TEvent
@event)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;EventPlayer&lt;/span&gt;&amp;lt;TEvent&amp;gt;(@event,
uncommitedEvents);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        ... rest of the
code here&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;struct&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;EventPlayer&lt;/span&gt;&amp;lt;TEvent&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt; TEvent
@event;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;UncommittedEvents&lt;/span&gt; uncommittedEvents;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; EventPlayer(TEvent @event, &lt;span style="COLOR: #2b91af"&gt;UncommittedEvents&lt;/span&gt; uncommittedEvents)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.@event = @event;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.uncommittedEvents = uncommittedEvents;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
With(&lt;span style="COLOR: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;TEvent&amp;gt; handler)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
handler(@event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
uncommittedEvents.Append(@event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This way, methods are referenced at least once with type check.&lt;/p&gt;
&lt;p&gt;My mind is still not set… What do you prefer ?&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=hzMSb2CMLmA:k4iiD3PErQ0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=hzMSb2CMLmA:k4iiD3PErQ0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=hzMSb2CMLmA:k4iiD3PErQ0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=hzMSb2CMLmA:k4iiD3PErQ0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=hzMSb2CMLmA:k4iiD3PErQ0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=hzMSb2CMLmA:k4iiD3PErQ0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=hzMSb2CMLmA:k4iiD3PErQ0:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=hzMSb2CMLmA:k4iiD3PErQ0:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/hzMSb2CMLmA" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2009/11/03/Event-Sourcing-and-CQRS-Dispatch-options#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/457356</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2009/11/03/Event-Sourcing-and-CQRS-Dispatch-options</feedburner:origLink></entry>
    
  <entry>
    <title>Event Sourcing and CQRS, Let's use it.</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/CYfRAHe1pv4/Event-Sourcing-and-CQRS-Lets-use-it" rel="alternate" type="text/html" title="Event Sourcing and CQRS, Let's use it." />
    <id>urn:md5:eafbc0de36bd89e388aa5565768037e9</id>
    <updated>2009-11-02T15:45:00+01:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>Domain Driven Design</dc:subject>
        <dc:subject>CQRS</dc:subject><dc:subject>Design</dc:subject><dc:subject>Distributed Domain Driven Design</dc:subject><dc:subject>Domain Driven Design</dc:subject><dc:subject>Reporting</dc:subject><dc:subject>Repository</dc:subject><dc:subject>Service Bus</dc:subject>    
    <content type="html">    &lt;p&gt;&lt;a href="http://thinkbeforecoding.com/post/2009/10/30/Event-Sourcing-and-CQRS%2C-Now-%21" target="_blank"&gt;Last time&lt;/a&gt;, we started a very basic Event Sourcing/Domain
Events/CQRS framework. &lt;em&gt;Be careful, I made an edit in the nested
DomainEvents+Handler&amp;lt;T&amp;gt;.Handles&amp;lt;E&amp;gt;() method, the
AggregateRoot.Replay method will not work as is, but we won’t need it.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We’ll build an equally simplistic application for personal library
management.&lt;/p&gt;
&lt;p&gt;The Ubiquitous Language will be minimal.&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;Book&lt;/strong&gt; can be &lt;strong&gt;Registered&lt;/strong&gt; with a
&lt;strong&gt;Title&lt;/strong&gt; and an &lt;strong&gt;ISBN&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;Book&lt;/strong&gt; can be &lt;strong&gt;Lent&lt;/strong&gt; to a
&lt;strong&gt;Borrower&lt;/strong&gt; at some &lt;strong&gt;Date&lt;/strong&gt; for an &lt;strong&gt;Expected
Time Span&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;Book&lt;/strong&gt; can then be &lt;strong&gt;Returned&lt;/strong&gt;. If it is
&lt;strong&gt;Returned&lt;/strong&gt; after &lt;strong&gt;Expected Time Span&lt;/strong&gt;, the return
is &lt;strong&gt;Late&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;That’s enough for our first try.&lt;/p&gt;
&lt;h2&gt;The Command Context&lt;/h2&gt;
&lt;h3&gt;The State Change Events&lt;/h3&gt;
&lt;p&gt;Here is the code for the three events that we found in the Ubiquitous
language:&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;BookRegistered&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; Id;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; Title;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; Isbn;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; BookRegistered(&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; id, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;
title, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; isbn)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            Id = id;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            Title =
title;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            Isbn =
isbn;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;BookLent&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; Id;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; Borrower;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;DateTime&lt;/span&gt; Date;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;TimeSpan&lt;/span&gt; ExpectedDuration;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; BookLent(&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt;
id, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; borrower, &lt;span style="COLOR: #2b91af"&gt;DateTime&lt;/span&gt; date,&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
              
&lt;span style="COLOR: #2b91af"&gt;TimeSpan&lt;/span&gt; expectedDuration)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            Id = id;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            Borrower =
borrower;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            Date =
date;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
ExpectedDuration = expectedDuration;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;BookReturned&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; Id;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; By;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;TimeSpan&lt;/span&gt; After;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; Late;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; BookReturned(&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; id, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; @by,
&lt;span style="COLOR: #2b91af"&gt;TimeSpan&lt;/span&gt; after,&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            
&lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; late)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            Id = id;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            By = by;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            After =
after;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            Late =
late;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;These events will usually be serialized to the event storage and on a
service bus, but here everything runs in memory.&lt;/p&gt;
&lt;h3&gt;The Book Aggregate Root&lt;/h3&gt;
&lt;p&gt;The book will need to be referenced by an identity in our system. We’ll hide
a Guid behind a BookId struct :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;struct&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; : &lt;span style="COLOR: #2b91af"&gt;IEquatable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt;&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Guid&lt;/span&gt; id;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; BookId(&lt;span style="COLOR: #2b91af"&gt;Guid&lt;/span&gt;
id) { &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.id = id; }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; NewBookId() { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt;(&lt;span style="COLOR: #2b91af"&gt;Guid&lt;/span&gt;.NewGuid()); }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt;
Equals(&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; other) { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; other.id.Equals(id); }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; Equals(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; obj)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (ReferenceEquals(&lt;span style="COLOR: blue"&gt;null&lt;/span&gt;,
obj)) &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: blue"&gt;false&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (obj.GetType() != &lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt;))
&lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: blue"&gt;false&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; Equals((&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt;)obj);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;int&lt;/span&gt; GetHashCode() { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; id.GetHashCode(); }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Now, the Book class itself :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;&lt;span style="COLOR: blue"&gt;  public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Book&lt;/span&gt;
: AggregateRoot&amp;lt;&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt;&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;  {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; id;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; title;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; isbn;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;
borrower;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;DateTime&lt;/span&gt;
date;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;TimeSpan&lt;/span&gt;
expectedDuration;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; Book(&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; id,
&lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt; events)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.id = id;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
&lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;dynamic&lt;/span&gt; @event &lt;span style="COLOR: blue"&gt;in&lt;/span&gt;
events)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
             
Apply(@event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; Book(&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; id,
&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; title, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; isbn)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.id = id;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; @event = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; BookRegistered(id, title, isbn);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
Apply(@event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
Append(@event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; Id { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; id; } }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
Lend(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; borrower, &lt;span style="COLOR: #2b91af"&gt;DateTime&lt;/span&gt; date,&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                             
&lt;span style="COLOR: #2b91af"&gt;TimeSpan&lt;/span&gt; expectedDuration)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
&lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.borrower != &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
             
&lt;span style="COLOR: blue"&gt;throw&lt;/span&gt; &lt;span style="COLOR: blue"&gt;new&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="COLOR: #a31515"&gt;&amp;quot;The book is already lent.&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; @event =&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; BookLent(id, borrower, date,
expectedDuration);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
Apply(@event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
Append(@event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
Return(&lt;span style="COLOR: #2b91af"&gt;DateTime&lt;/span&gt; returnDate)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
&lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (borrower == &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
             
&lt;span style="COLOR: blue"&gt;throw&lt;/span&gt; &lt;span style="COLOR: blue"&gt;new&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="COLOR: #a31515"&gt;&amp;quot;The book has not been lent.&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
&lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (returnDate &amp;lt; date)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
             
&lt;span style="COLOR: blue"&gt;throw&lt;/span&gt; &lt;span style="COLOR: blue"&gt;new&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;ArgumentException&lt;/span&gt;(&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: #a31515"&gt;&amp;quot;The book cannot be returned before being
lent.&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; actualDuration = returnDate - date;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; @event = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; BookReturned(&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                        
id,&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                        
borrower,&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                        
actualDuration,&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                        
actualDuration &amp;gt; expectedDuration);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
Apply(@event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
Append(@event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
Apply(BookRegistered @event)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
title = @event.Title;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
isbn = @event.Isbn;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
Apply(BookLent @event)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
borrower = @event.Borrower;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
date = @event.Date;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
expectedDuration = @event.ExpectedDuration;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
Apply(BookReturned @event)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;         
borrower = &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;      }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;  }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The class implements AggregateRoot&amp;lt;BookId&amp;gt; and so provides an
explicitly implemented UncommittedEvents property.&lt;/p&gt;
&lt;p&gt;The first .ctor is used to load the Aggregate Root, the second one is used
to build a new Aggregate Root.&lt;/p&gt;
&lt;p&gt;The public methods (Lend and Return) are the commands on the Aggregate Root
as defined in the Ubiquitous Language.&lt;/p&gt;
&lt;p&gt;The structure is always the same :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Validate arguments and state&lt;/li&gt;
&lt;li&gt;Prepare state transition using domain logic&lt;/li&gt;
&lt;li&gt;Apply state transition (no domain logic should happen here)&lt;/li&gt;
&lt;li&gt;Append state transition to uncommitted events&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first .ctor uses dynamic to dispatch each event object on the
corresponding specific Apply method. In case you implement the pattern is
previous C# version, it is advised to provide a Replay method in the base class
that will perform the dynamic dispatch based on reflection.&lt;/p&gt;
&lt;p&gt;That’s all for the entity. No ORM, no mapping… easy.&lt;/p&gt;
&lt;h3&gt;The Repository&lt;/h3&gt;
&lt;p&gt;It is often clearer to provide a specific repository interface that exposes
only available methods. With event sourcing, it’s not that useful… we’ll write
it anyway in case you’d like to use dependency injection. The interface is part
of the domain and should be in the same assembly as the entity and the
events.&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;interface&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IBookRepository&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Add(&lt;span style="COLOR: #2b91af"&gt;Book&lt;/span&gt;
book);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: #2b91af"&gt;Book&lt;/span&gt; &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;[&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; id] { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;;
}&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The implementation will simply derive from the Repository base class, it can
be in the application assembly.&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;BookRepository&lt;/span&gt; :&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;       
Repository&amp;lt;&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt;, &lt;span style="COLOR: #2b91af"&gt;Book&lt;/span&gt;&amp;gt;,&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: #2b91af"&gt;IBookRepository&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;Book&lt;/span&gt; CreateInstance(&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; id,&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt; events)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Book&lt;/span&gt;(id, events);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Add and the indexer are implemented by the base class. The only thing to
provide is a way to instantiate the class with expected parameters.&lt;/p&gt;
&lt;p&gt;We could use Activator.CreateInstance or reflection to provide a generic
implementation. I choose to make it simpler to read.&lt;/p&gt;
&lt;h2&gt;The Query context&lt;/h2&gt;
&lt;h3&gt;The Report Database&lt;/h3&gt;
&lt;p&gt;We’ll mimic a reporting table of book lent state :&lt;/p&gt;
&lt;p&gt;This would be the data returned from table rows :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;BookState&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; Id {
&lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;;
}&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; Title {
&lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;;
}&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; Lent {
&lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;;
}&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;And this will hide the data table implementation :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;interface&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IBookStateQuery&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;BookState&lt;/span&gt;&amp;gt; GetBookStates();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: #2b91af"&gt;BookState&lt;/span&gt; GetBookState(&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; id);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;BookState&lt;/span&gt;&amp;gt; GetLentBooks();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; AddBookState(&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; id, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;
title);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; SetLent(&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt;
id, &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; lent);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;We can simply query data to report in the UI, and update data state.&lt;/p&gt;
&lt;p&gt;Implementation will be in memory for now :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;&lt;span style="COLOR: blue"&gt;    class&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;BookStateQuery&lt;/span&gt; : &lt;span style="COLOR: #2b91af"&gt;IBookStateQuery&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt;, &lt;span style="COLOR: #2b91af"&gt;BookState&lt;/span&gt;&amp;gt; states =&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                    
&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt;, &lt;span style="COLOR: #2b91af"&gt;BookState&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;BookState&lt;/span&gt;&amp;gt; GetBookStates()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; states.Values;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;BookState&lt;/span&gt;
GetBookState(&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; id)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; states[id];&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;BookState&lt;/span&gt;&amp;gt; GetLentBooks()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; states.Values.Where(b =&amp;gt; b.Lent);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
AddBookState(&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; id, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; title)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; state = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;BookState&lt;/span&gt; { Id = id, Title = title };&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
states.Add(id, state);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
SetLent(&lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt; id, &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; lent)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
states[id].Lent = lent;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The important point here is that no domain logic occurs.&lt;/p&gt;
&lt;p&gt;A RDBMS implementation could use an ORM or simply build DTOs from a
DataReader.&lt;/p&gt;
&lt;h2&gt;The event handlers&lt;/h2&gt;
&lt;p&gt;We can now denormalize domain states to the reporting database using an
event handler :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;&lt;span style="COLOR: blue"&gt;    class&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;BookStateHandler&lt;/span&gt; :&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    Handles&amp;lt;&lt;span style="COLOR: #2b91af"&gt;BookRegistered&lt;/span&gt;&amp;gt;,&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    Handles&amp;lt;&lt;span style="COLOR: #2b91af"&gt;BookLent&lt;/span&gt;&amp;gt;,&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    Handles&amp;lt;&lt;span style="COLOR: #2b91af"&gt;BookReturned&lt;/span&gt;&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;IBookStateQuery&lt;/span&gt; stateQuery;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; BookStateHandler(&lt;span style="COLOR: #2b91af"&gt;IBookStateQuery&lt;/span&gt; stateQuery)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.stateQuery = stateQuery;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
Handle(&lt;span style="COLOR: #2b91af"&gt;BookRegistered&lt;/span&gt; @event)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
stateQuery.AddBookState(@event.Id, @event.Title);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
Handle(&lt;span style="COLOR: #2b91af"&gt;BookLent&lt;/span&gt; @event)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="COLOR: #a31515"&gt;&amp;quot;Book
lent to {0}&amp;quot;&lt;/span&gt;, @event.Borrower);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
stateQuery.SetLent(@event.Id, &lt;span style="COLOR: blue"&gt;true&lt;/span&gt;);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
Handle(&lt;span style="COLOR: #2b91af"&gt;BookReturned&lt;/span&gt; @event)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="COLOR: #a31515"&gt;&amp;quot;Book
returned by {0}&amp;quot;&lt;/span&gt;, @event.By);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
stateQuery.SetLent(@event.Id, &lt;span style="COLOR: blue"&gt;false&lt;/span&gt;);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The Console.WriteLine are here to view when things happen, you would usually
not use it in your production code. Logging this would not provide much
benefits since all the events are already stored in the EventStorage.&lt;/p&gt;
&lt;p&gt;Using this handler, the IBookStateQuery will be up to date with current
Command Context state. In an asynchronous environment, this is where eventual
consistency is introduced.&lt;/p&gt;
&lt;p&gt;We will also add a service that will notify when a user returned a book too
late :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;class&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;LateReturnNotifier&lt;/span&gt; :&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    Handles&amp;lt;&lt;span style="COLOR: #2b91af"&gt;BookReturned&lt;/span&gt;&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
Handle(&lt;span style="COLOR: #2b91af"&gt;BookReturned&lt;/span&gt; @event)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (@event.Late)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="COLOR: #a31515"&gt;&amp;quot;{0} was late&amp;quot;&lt;/span&gt;, @event.By);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Here again, no domain logic, we just do the infrastructure stuff, usually
sending an email or a SMS.&lt;/p&gt;
&lt;h2&gt;View it in Action&lt;/h2&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;&lt;span style="COLOR: blue"&gt;    class&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;Program&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
Main(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;[] args)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
ISessionFactory factory = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt;
SessionFactory(&lt;span style="COLOR: blue"&gt;new&lt;/span&gt;
EventStorage());               
&lt;span style="COLOR: #2b91af"&gt;IBookStateQuery&lt;/span&gt; query = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;BookStateQuery&lt;/span&gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
DomainEvents.RegisterHanlder(() =&amp;gt; &lt;span style="COLOR: blue"&gt;new&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;BookStateHandler&lt;/span&gt;(query));&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
DomainEvents.RegisterHanlder(() =&amp;gt; &lt;span style="COLOR: blue"&gt;new&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;LateReturnNotifier&lt;/span&gt;());&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; bookId = &lt;span style="COLOR: #2b91af"&gt;BookId&lt;/span&gt;.NewBookId();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;using&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; session =
factory.OpenSession())&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; books = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;BookRepository&lt;/span&gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
books.Add(&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Book&lt;/span&gt;(bookId,&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                  
&lt;span style="COLOR: #a31515"&gt;&amp;quot;The Lord of the Rings&amp;quot;&lt;/span&gt;,&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                  
&lt;span style="COLOR: #a31515"&gt;&amp;quot;0-618-15396-9&amp;quot;&lt;/span&gt;));&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
session.SubmitChanges();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
ShowBooks(query);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;using&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; session =
factory.OpenSession())&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; books = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;BookRepository&lt;/span&gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; book = books[bookId];&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
book.Lend(&lt;span style="COLOR: #a31515"&gt;&amp;quot;Alice&amp;quot;&lt;/span&gt;,&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                    
&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;DateTime&lt;/span&gt;(2009, 11, 2),&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                    
&lt;span style="COLOR: #2b91af"&gt;TimeSpan&lt;/span&gt;.FromDays(14));&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
session.SubmitChanges();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
ShowBooks(query);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;using&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; session =
factory.OpenSession())&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; books = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;BookRepository&lt;/span&gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; book = books[bookId];&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
book.Return(&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;DateTime&lt;/span&gt;(2009, 11, 8));&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
session.SubmitChanges();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
ShowBooks(query);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;using&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; session =
factory.OpenSession())&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; books = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;BookRepository&lt;/span&gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; book = books[bookId];&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
book.Lend(&lt;span style="COLOR: #a31515"&gt;&amp;quot;Bob&amp;quot;&lt;/span&gt;,&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                     
&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;DateTime&lt;/span&gt;(2009, 11, 9),&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                     
&lt;span style="COLOR: #2b91af"&gt;TimeSpan&lt;/span&gt;.FromDays(14));&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
session.SubmitChanges();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
ShowBooks(query);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;using&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; session =
factory.OpenSession())&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; books = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;BookRepository&lt;/span&gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; book = books[bookId];&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
book.Return(&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;DateTime&lt;/span&gt;(2010, 03, 1));&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
session.SubmitChanges();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
ShowBooks(query);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;void&lt;/span&gt; ShowBooks(&lt;span style="COLOR: #2b91af"&gt;IBookStateQuery&lt;/span&gt; query)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; state
&lt;span style="COLOR: blue"&gt;in&lt;/span&gt; query.GetBookStates())&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="COLOR: #a31515"&gt;&amp;quot;{0} is {1}.&amp;quot;&lt;/span&gt;,&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                      
state.Title,&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                      
state.Lent ? &lt;span style="COLOR: #a31515"&gt;&amp;quot;lent&amp;quot;&lt;/span&gt; : &lt;span style="COLOR: #a31515"&gt;&amp;quot;home&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;We start by instantiating storage for the command context (the
ISessionFactory) and the query context (the &lt;span style="COLOR: #2b91af"&gt;IBookStateQuery&lt;/span&gt;). In production you’ll use persistent
storages (a persistent event storage and a RDBMS). I highly recommend using a
Dependency Injection Container for real size projects.&lt;/p&gt;
&lt;p&gt;Then we wire the handlers on domain events.&lt;/p&gt;
&lt;p&gt;The application can start.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We register a book in the library.&lt;/li&gt;
&lt;li&gt;We lend it to Alice on 2009-11-02 for 14 days&lt;/li&gt;
&lt;li&gt;She returns it on 2009-11-08, she’s on time&lt;/li&gt;
&lt;li&gt;We lend it to Bob on 2009-11-09 for 14 days,&lt;/li&gt;
&lt;li&gt;He returns it on 2010-03-01, he’s late&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The output is the following :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;The Lord of the Rings &lt;span style="COLOR: blue"&gt;is&lt;/span&gt;
home.    &lt;span style="COLOR: green"&gt;// written from
state&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;Book lent to
Alice               
&lt;span style="COLOR: green"&gt;// written by the book state handler&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;The Lord of the Rings &lt;span style="COLOR: blue"&gt;is&lt;/span&gt;
lent.    &lt;span style="COLOR: green"&gt;// written from
state&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;Book returned by
Alice           
&lt;span style="COLOR: green"&gt;// written by the book state handler&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;The Lord of the Rings &lt;span style="COLOR: blue"&gt;is&lt;/span&gt;
home.    &lt;span style="COLOR: green"&gt;// written from
state&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;Book lent to
Bob                 
&lt;span style="COLOR: green"&gt;// written by the book state handler&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;The Lord of the Rings &lt;span style="COLOR: blue"&gt;is&lt;/span&gt;
lent.    &lt;span style="COLOR: green"&gt;// written from
state&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;Book returned by
Bob             
&lt;span style="COLOR: green"&gt;// written by the book state handler&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;Bob was
late                     
&lt;span style="COLOR: green"&gt;// written by the late return notifier&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;The Lord of the Rings &lt;span style="COLOR: blue"&gt;is&lt;/span&gt;
home.    &lt;span style="COLOR: green"&gt;// written from
state&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;We have here a clear separation between Command that handles the domain
logic and Query that handles presentation logic.&lt;/p&gt;
&lt;p&gt;Have fun. Questions and remarks expected !&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=CYfRAHe1pv4:0-8iycDB6VM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=CYfRAHe1pv4:0-8iycDB6VM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=CYfRAHe1pv4:0-8iycDB6VM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=CYfRAHe1pv4:0-8iycDB6VM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=CYfRAHe1pv4:0-8iycDB6VM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=CYfRAHe1pv4:0-8iycDB6VM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=CYfRAHe1pv4:0-8iycDB6VM:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=CYfRAHe1pv4:0-8iycDB6VM:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/CYfRAHe1pv4" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2009/11/02/Event-Sourcing-and-CQRS-Lets-use-it#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/457100</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2009/11/02/Event-Sourcing-and-CQRS-Lets-use-it</feedburner:origLink></entry>
    
  <entry>
    <title>Event Sourcing and CQRS, Now !</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/zeQtwGPdAK0/Event-Sourcing-and-CQRS-Now" rel="alternate" type="text/html" title="Event Sourcing and CQRS, Now !" />
    <id>urn:md5:e543def22b2926eeb3ba9146b58c31e0</id>
    <updated>2009-10-30T15:53:00+01:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>Domain Driven Design</dc:subject>
        <dc:subject>CQRS</dc:subject><dc:subject>Distributed Domain Driven Design</dc:subject><dc:subject>Domain Driven Design</dc:subject><dc:subject>Repository</dc:subject>    
    <content type="html">    &lt;p&gt;Enough talking, Action !&lt;/p&gt;
&lt;p&gt;Today, we will build a basic event sourcing infrastructure. Get the beta 2
of Visual Studio 2010, we’ll be using C# dynamic features to go straight to our
goal.&lt;/p&gt;
&lt;h2&gt;Then Event Storage&lt;/h2&gt;
&lt;p&gt;Let’s hide the ugly details of the event storage behind two simple
interfaces :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;&lt;span style="COLOR: blue"&gt;    public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;interface&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IEventStorage&lt;/span&gt; : &lt;span style="COLOR: #2b91af"&gt;IDisposable&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: #2b91af"&gt;IAggregateRootStorage&lt;/span&gt;&amp;lt;TId&amp;gt;
GetAggregateRootStore&amp;lt;TAggregateRoot, TId&amp;gt;()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;where&lt;/span&gt; TAggregateRoot : AggregateRoot&amp;lt;TId&amp;gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;interface&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IAggregateRootStorage&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;in&lt;/span&gt; TId&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Append(TId id, &lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt; events);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;[TId id] {
&lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;And we start with a minimal in memory implementation, the event storage
first :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;&lt;span style="COLOR: blue"&gt;    public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;EventStorage&lt;/span&gt; : &lt;span style="COLOR: #2b91af"&gt;IEventStorage&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Type&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;dynamic&lt;/span&gt;&amp;gt;
stores = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Type&lt;/span&gt;,
&lt;span style="COLOR: blue"&gt;dynamic&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IAggregateRootStorage&lt;/span&gt;&amp;lt;TId&amp;gt;
GetAggregateRootStorage&amp;lt;TAggregateRoot, TId&amp;gt;()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;&lt;span style="COLOR: blue"&gt;          
where&lt;/span&gt; TAggregateRoot : AggregateRoot&amp;lt;TId&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;dynamic&lt;/span&gt; store;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (!stores.TryGetValue(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(TAggregateRoot), &lt;span style="COLOR: blue"&gt;out&lt;/span&gt; store))&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
store = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt;
AggregateRootStorage&amp;lt;TId&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
stores.Add(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt; (TAggregateRoot),
store);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; store;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Dispose()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
stores.Clear();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Here I could replace dynamic by object, and cast to requested type on
return. I use dynamic because this kind of code is not compile time safe
anyway. There’s a specific storage for each Aggregate Root type, especially
depending on identifier type, for type safety.&lt;/p&gt;
&lt;p&gt;Then the AggregateRootStorage :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;&lt;span style="COLOR: blue"&gt;    class&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;AggregateRootStorage&lt;/span&gt;&amp;lt;TId&amp;gt; :
&lt;span style="COLOR: #2b91af"&gt;IAggregateRootStorage&lt;/span&gt;&amp;lt;TId&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;TId, &lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;
store = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;TId, &lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Append(TId
id, &lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt; events)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt;
aggregateRootEvents;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (!store.TryGetValue(id, &lt;span style="COLOR: blue"&gt;out&lt;/span&gt; aggregateRootEvents))&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
aggregateRootEvents = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
store.Add(id, aggregateRootEvents);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
aggregateRootEvents.AddRange(events);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;[TId
id]&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; store[id];
}&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;It simply stores list of events associated with aggregate root
identifier.&lt;/p&gt;
&lt;h2&gt;The Aggregate Root&lt;/h2&gt;
&lt;p&gt;Aggregate roots manage uncommitted events :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;interface&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IUncommittedEvents&lt;/span&gt; : &lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; HasEvents { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;;
}&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Commit();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The interface can indicates whether there are events, returns the events,
and clears the uncommitted events by committing.&lt;/p&gt;
&lt;p&gt;Quick implementation :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;UncommittedEvents&lt;/span&gt; : &lt;span style="COLOR: #2b91af"&gt;IUncommittedEvents&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt; events = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
Append(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; @event)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
events.Add(@event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: #2b91af"&gt;IEnumerator&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt;.GetEnumerator()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; events.GetEnumerator();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; HasEvents&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; events.Count
!= 0; }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IUncommittedEvents&lt;/span&gt;.Commit()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
events.Clear();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: #2b91af"&gt;IEnumerator&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;.GetEnumerator()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; events.GetEnumerator();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Nothing tricky here neither.&lt;/p&gt;
&lt;p&gt;Now, the IAggregateRoot interface used by the repository gives access to the
uncommitted events:&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;&lt;span style="COLOR: blue"&gt;    public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;interface&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IAggregateRoot&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;out&lt;/span&gt;
TId&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        TId Id {
&lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: #2b91af"&gt;IUncommittedEvents&lt;/span&gt; UncommittedEvents { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The AggregateRoot class will maintain the uncommitted events :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;AggregateRoot&lt;/span&gt;&amp;lt;TId&amp;gt; : &lt;span style="COLOR: #2b91af"&gt;IAggregateRoot&lt;/span&gt;&amp;lt;TId&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;UncommittedEvents&lt;/span&gt; uncommittedEvents =
&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;UncommittedEvents&lt;/span&gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
Replay(&lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt; events)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            dynamic me =
&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; @event
&lt;span style="COLOR: blue"&gt;in&lt;/span&gt; events)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
me.Apply(@event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
Append(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; @event)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
uncommittedEvents.Append(@event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; TId Id {
&lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: #2b91af"&gt;IUncommittedEvents&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IAggregateRoot&lt;/span&gt;&amp;lt;TId&amp;gt;.UncommittedEvents&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt;
uncommittedEvents; }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The Append method will be use by child class to append events after they are
applied.&lt;/p&gt;
&lt;p&gt;The Replay method is used in the child class constructor to rebuild the
Aggregate Root state from events.&lt;/p&gt;
&lt;p&gt;Here I use a dynamic me variable to dispatch events on specific child class
Apply methods. A .Net 2 or 3.5 implementation would use reflection to dispatch
events on Apply methods.&lt;/p&gt;
&lt;p&gt;The UncommittedEvents property is implemented explicitly so that it does not
appear in standard class use.&lt;/p&gt;
&lt;h2&gt;The Repository&lt;/h2&gt;
&lt;p&gt;The repository is just very slightly longer. I added a session concept so
that several repositories can submit changes in a single transaction :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: blue"&gt;interface&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;ISessionItem&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; SubmitChanges();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;     &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Repository&lt;/span&gt;&amp;lt;TId, TAggregateRoot&amp;gt; :
ISessionItem&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;where&lt;/span&gt; TAggregateRoot : &lt;span style="COLOR: #2b91af"&gt;AggregateRoot&lt;/span&gt;&amp;lt;TId&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;TId, TAggregateRoot&amp;gt; users
= &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;TId, TAggregateRoot&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;IAggregateRootStorage&lt;/span&gt;&amp;lt;TId&amp;gt;
aggregateRootStorage;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; Repository()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
aggregateRootStorage = Session.Enlist(&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
Add(TAggregateRoot user)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
users.Add(user.Id, user);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; TAggregateRoot &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;[TId id]&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; Find(id) ??
Load(id); }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; TAggregateRoot Find(TId id)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
TAggregateRoot user;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; users.TryGetValue(id, &lt;span style="COLOR: blue"&gt;out&lt;/span&gt; user) ? user : &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; TAggregateRoot Load(TId id)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; events = aggregateRootStorage[id];&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; user = CreateInstance(id, events);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
users.Add(id, user);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; user;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt;
TAggregateRoot CreateInstance(TId id, &lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt; events);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
SubmitChanges()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: #2b91af"&gt;IAggregateRoot&lt;/span&gt;&amp;lt;TId&amp;gt; user &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; users.Values)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; uncomitedEvents =
user.UncommittedEvents;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (uncomitedEvents.HasEvents)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
{&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                   
aggregateRootStorage.Append(user.Id, uncomitedEvents);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                   
PublishEvents(uncomitedEvents);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                   
uncomitedEvents.Commit();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
}&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
users.Clear();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
PublishEvents(&lt;span style="COLOR: #2b91af"&gt;IUncommittedEvents&lt;/span&gt;
uncommittedEvents)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (dynamic @event &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; uncommittedEvents)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
DomainEvents.Raise(@event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The constructor enlist the repository in current session.&lt;/p&gt;
&lt;p&gt;The Add method registers the aggregate root in the repository, its events
will be persisted in SubmitChanges()&lt;/p&gt;
&lt;p&gt;The indexer finds an entity already in memory or loads it from the event
store. The abstract CreateInstance method implementation will be responsible
for instantiation.&lt;/p&gt;
&lt;p&gt;Submit changes does what is expected, and also publish committed events.
Will see the trick with dynamic @events when we analyze domain events.&lt;/p&gt;
&lt;h2&gt;The Session and its Factory&lt;/h2&gt;
&lt;p&gt;Just to group the SubmitChanges on several repositories :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;interface&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;ISessionFactory&lt;/span&gt; : &lt;span style="COLOR: #2b91af"&gt;IDisposable&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: #2b91af"&gt;ISession&lt;/span&gt; OpenSession();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;SessionFactory&lt;/span&gt; : &lt;span style="COLOR: #2b91af"&gt;ISessionFactory&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;IEventStorage&lt;/span&gt; eventStorage;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; SessionFactory(&lt;span style="COLOR: #2b91af"&gt;IEventStorage&lt;/span&gt; eventStorage)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.eventStorage = eventStorage;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;ISession&lt;/span&gt;
OpenSession()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Session&lt;/span&gt;(eventStorage);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Dispose()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
eventStorage.Dispose();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;interface&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;ISession&lt;/span&gt; : &lt;span style="COLOR: #2b91af"&gt;IDisposable&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; SubmitChanges();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Session&lt;/span&gt; : &lt;span style="COLOR: #2b91af"&gt;ISession&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;IEventStorage&lt;/span&gt; eventStorage;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;HashSet&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;ISessionItem&lt;/span&gt;&amp;gt; enlistedItems = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;HashSet&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;ISessionItem&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        [&lt;span style="COLOR: #2b91af"&gt;ThreadStatic&lt;/span&gt;] &lt;span style="COLOR: blue"&gt;private&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Session&lt;/span&gt; current;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; Session(&lt;span style="COLOR: #2b91af"&gt;IEventStorage&lt;/span&gt; eventStorage)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.eventStorage = eventStorage;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (current != &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;throw&lt;/span&gt; &lt;span style="COLOR: blue"&gt;new&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="COLOR: #a31515"&gt;&amp;quot;Cannot nest unit of work&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            current =
&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;Session&lt;/span&gt; Current&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; current;
}&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt;
SubmitChanges()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; enlisted
&lt;span style="COLOR: blue"&gt;in&lt;/span&gt; enlistedItems)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
enlisted.SubmitChanges();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
enlistedItems.Clear();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Dispose()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            current =
&lt;span style="COLOR: blue"&gt;null&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;IAggregateRootStorage&lt;/span&gt;&amp;lt;TId&amp;gt;
Enlist&amp;lt;TId, TAggregateRoot&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                       
(&lt;span style="COLOR: #2b91af"&gt;Repository&lt;/span&gt;&amp;lt;TId, TAggregateRoot&amp;gt;
repository)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;where&lt;/span&gt; TAggregateRoot : &lt;span style="COLOR: #2b91af"&gt;AggregateRoot&lt;/span&gt;&amp;lt;TId&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; unitOfWork = Current;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
unitOfWork.enlistedItems.Add(repository);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt;
unitOfWork.eventStorage.GetAggregateRootStorage&amp;lt;TAggregateRoot,
TId&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Ok almost everything is here. The last part, for events to be used by other
parts of the system, needed to go CQRS.&lt;/p&gt;
&lt;h2&gt;Domain Events&lt;/h2&gt;
&lt;p&gt;Here, I made a minor variation on &lt;a href="http://www.udidahan.com/2009/06/14/domain-events-salvation/" target="_blank"&gt;Udi Dahan’s DomainEvents&lt;/a&gt; implementation :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;DomainEvents&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        [&lt;span style="COLOR: #2b91af"&gt;ThreadStatic&lt;/span&gt;] &lt;span style="COLOR: blue"&gt;private&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Delegate&lt;/span&gt;&amp;gt; actions;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Handler&lt;/span&gt;&amp;gt; handlers;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Register&amp;lt;T&amp;gt;(&lt;span style="COLOR: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;T&amp;gt; callback)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (actions == &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;)
actions = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Delegate&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
actions.Add(callback);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;void&lt;/span&gt; RegisterHanlder&amp;lt;T&amp;gt;(&lt;span style="COLOR: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T&amp;gt; factory)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (handlers == &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;)
handlers = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Handler&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
handlers.Add(&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Handler&lt;/span&gt;&amp;lt;T&amp;gt;(factory));&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: green"&gt;//Raises the given domain
event      &lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Raise&amp;lt;T&amp;gt;(T @event)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (actions != &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: #2b91af"&gt;Delegate&lt;/span&gt; action &lt;span style="COLOR: blue"&gt;in&lt;/span&gt;
actions)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                   
&lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (action &lt;span style="COLOR: blue"&gt;is&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;T&amp;gt;)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                       
((&lt;span style="COLOR: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;T&amp;gt;) action)(@event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (handlers != &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;var&lt;/span&gt;
h &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; handlers)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
{&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                   
&lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (h.Handles&amp;lt;T&amp;gt;())&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                   
{&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                       
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; handler= h.CreateInstance&amp;lt;T&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                       
handler.Handle(@event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                   
}&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
}&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Handler&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; Handles&amp;lt;E&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;Handles&lt;/span&gt;&amp;lt;E&amp;gt;
CreateInstance&amp;lt;E&amp;gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;Handler&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="COLOR: #2b91af"&gt;Handler&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T&amp;gt; factory;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; Handler(&lt;span style="COLOR: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;T&amp;gt; factory)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.factory = factory;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; Handles&amp;lt;E&amp;gt;()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;
(Handles&amp;lt;E&amp;gt;)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
                  
.IsAssignableFrom(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt; (T));&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;Handles&lt;/span&gt;&amp;lt;E&amp;gt;
CreateInstance&amp;lt;E&amp;gt;()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
&lt;span style="COLOR: blue"&gt;return&lt;/span&gt; (&lt;span style="COLOR: #2b91af"&gt;Handles&lt;/span&gt;&amp;lt;E&amp;gt;)factory();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;interface&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Handles&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;in&lt;/span&gt;
T&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Handle(T @event);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Edit : Changed the Handles&amp;lt;E&amp;gt;, T should be casted as
Handles&amp;lt;E&amp;gt;, not as E, of course.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Event handlers can be registerd as Action&amp;lt;T&amp;gt; delegates or as class
that implements once or more Handles&amp;lt;T&amp;gt;.&lt;/p&gt;
&lt;p&gt;The private Handler and Handler&amp;lt;T&amp;gt; classes are used to find handlers
that handles a specific message and dispatch it, without using a Dependency
Injection Container like Udi’s implementation.&lt;/p&gt;
&lt;p&gt;The simple dynamic-fu in the repository was to call
DomainEvents.Raise&amp;lt;T&amp;gt; using a dynamic dispatch. This way, Raise is always
called with the actual event type in T. No tricky reflection is needed for the
dispatch. inside Raise&amp;lt;T&amp;gt;, we can the rely on T as being the actual event
type. Funky !&lt;/p&gt;
&lt;h2&gt;Next Time…&lt;/h2&gt;
&lt;p&gt;There’s already a lot of code for a single post, every thing is in place at
infrastructure level. You can already try it for yourself if you can figure how
to.&lt;/p&gt;
&lt;p&gt;The sample will come in the next post, stay tuned.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=zeQtwGPdAK0:7BScoAL78ws:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=zeQtwGPdAK0:7BScoAL78ws:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=zeQtwGPdAK0:7BScoAL78ws:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=zeQtwGPdAK0:7BScoAL78ws:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=zeQtwGPdAK0:7BScoAL78ws:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=zeQtwGPdAK0:7BScoAL78ws:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=zeQtwGPdAK0:7BScoAL78ws:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=zeQtwGPdAK0:7BScoAL78ws:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/zeQtwGPdAK0" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2009/10/30/Event-Sourcing-and-CQRS-Now#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/456396</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2009/10/30/Event-Sourcing-and-CQRS-Now</feedburner:origLink></entry>
    
  <entry>
    <title>Uniqueness validation in CQRS Architecture</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/d45sXrk8FeQ/Uniqueness-validation-in-CQRS-Architecture" rel="alternate" type="text/html" title="Uniqueness validation in CQRS Architecture" />
    <id>urn:md5:82558467f5ecabab166064b6f33d5e27</id>
    <updated>2009-10-28T15:05:00+01:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>Domain Driven Design</dc:subject>
        <dc:subject>CQRS</dc:subject><dc:subject>Design</dc:subject><dc:subject>Distributed Domain Driven Design</dc:subject><dc:subject>Domain Driven Design</dc:subject>    
    <content type="html">    &lt;p&gt;This is a short follow up on &lt;a href="http://bjarte.com/post/224749430/set-based-validation-in-the-cqrs-architecture" target="_blank"&gt;Bjarte’s Post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There’s an important thing to consider when needing set validation :
&lt;strong&gt;why&lt;/strong&gt; ?&lt;/p&gt;
&lt;p&gt;Why do these things need to be considered together and cannot just be
handled separately ?&lt;/p&gt;
&lt;p&gt;We can distinct two different parameters in uniqueness, Cardinality and
Scope.&lt;/p&gt;
&lt;h2&gt;Cardinality&lt;/h2&gt;
&lt;p&gt;There are mainly two types of cardinality :&lt;/p&gt;
&lt;h3&gt;1 Cardinality&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Only one employee can be the boss.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The model could provide a IsBoss property on every employee… But constancy
would be very hard to achieve, especially in a CQRS architecture.&lt;/p&gt;
&lt;p&gt;We should read the preceding rule as :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The company has only one boss. The boss is an employee.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now, we can model a Boss property on the Company Aggregate Root that will
reference the employee that is the boss. Changing the boss can now be an atomic
and consistent operation.&lt;/p&gt;
&lt;p&gt;We can see that we had to introduce a upper level to manage it (we’ll se it
in the Scope section).&lt;/p&gt;
&lt;h3&gt;n Cardinality&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Employee should have different user names.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We can clearly see here that user names must be different because they’ll
act as identifiers. This is the goal of almost any uniqueness constraint. The
property will be used as a key in a lookup.&lt;/p&gt;
&lt;p&gt;The 1 (or 2 or 3) cardinality also act this way. It’s a way to tag an
entity. You can ask “who is the boss ?” and get the answer by a simple lookup
at the Boss property that acts like a bucket in a hash table.&lt;/p&gt;
&lt;h3&gt;Scope&lt;/h3&gt;
&lt;h3&gt;There is no such thing as global scope&lt;/h3&gt;
&lt;p&gt;Even when we say, “Employee should have different user names”, there is a
implicit scope, the Company.&lt;/p&gt;
&lt;p&gt;Even when we say, “You Id Card number should be unique”, understand, “at the
Country scope”.&lt;/p&gt;
&lt;p&gt;Even when we say, “Your DNA should be unique”, understand, “At our life
understanding scope”.&lt;/p&gt;
&lt;p&gt;Find the scope and see the volume of data whose uniqueness should be
enforced.&lt;/p&gt;
&lt;p&gt;As we said, properties that have a uniqueness constraint are usually used as
lookup values to find those entities. As such they rarely take part in the
child entity domain logic.&lt;/p&gt;
&lt;p&gt;Instead of having a UserName property on the Employee entity, why not have a
UserNames key/value collection on the Company that will give the Employee for a
given user name ?&lt;/p&gt;
&lt;p&gt;If the expected Employee count is expected to be in a limited range, this is
the most appropriate solution.&lt;/p&gt;
&lt;p&gt;If the number can grow, loading it in memory on each Company hydratation is
a bit heavy, so keep the directory on disk (using a table with a unique key in
a RDBMS as suggested by Bjarte) or any other way that provide the expected
performance.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In every case, when a uniqueness constraint appear on a property, the
property does not belong the the entity itself but should be viewed as a key to
access the entity from the upper level scope.&lt;/p&gt;
&lt;p&gt;Do you have examples that cannot be solved this way ?&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=d45sXrk8FeQ:8iYGz_LkU_4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=d45sXrk8FeQ:8iYGz_LkU_4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=d45sXrk8FeQ:8iYGz_LkU_4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=d45sXrk8FeQ:8iYGz_LkU_4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=d45sXrk8FeQ:8iYGz_LkU_4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=d45sXrk8FeQ:8iYGz_LkU_4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=d45sXrk8FeQ:8iYGz_LkU_4:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=d45sXrk8FeQ:8iYGz_LkU_4:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/d45sXrk8FeQ" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2009/10/28/Uniqueness-validation-in-CQRS-Architecture#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/455931</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2009/10/28/Uniqueness-validation-in-CQRS-Architecture</feedburner:origLink></entry>
    
  <entry>
    <title>C# Static interfaces - Take 2</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/BiT44qCLfO4/CSharp-Static-interfaces-Take-2" rel="alternate" type="text/html" title="C# Static interfaces - Take 2" />
    <id>urn:md5:427b70acb34a7bfbd2b0e293ca301a03</id>
    <updated>2009-10-22T15:11:00+02:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>.Net Framework</dc:subject>
        <dc:subject>.net</dc:subject><dc:subject>CSharp</dc:subject><dc:subject>Interfaces</dc:subject>    
    <content type="html">    &lt;p&gt;As &lt;a title="Codingly.com" href="http://codingly.com/" target="_blank"&gt;Romain&lt;/a&gt; was pointing in the comments, I totally missed to tell
where I wanted to go &lt;a href="http://thinkbeforecoding.com/post/2009/10/21/C-Static-interfaces" target="_blank"&gt;with this static interface things&lt;/a&gt;. Need more sleep these days…&lt;/p&gt;
&lt;p&gt;So here it is.&lt;/p&gt;
&lt;h2&gt;No I don’t want to do this&lt;/h2&gt;
&lt;p&gt;The point was not to enable something like this :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;&lt;span style="COLOR: blue"&gt;   int&lt;/span&gt; value =
&lt;span style="COLOR: #2b91af"&gt;ICountable&lt;/span&gt;.Count;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Static interfaces have no implementation exactly like interfaces.&lt;/p&gt;
&lt;p&gt;With interfaces, you need an instance (usually in a variable or member) to
find the actual implementation and call it. With static interfaces, you need a
type.&lt;/p&gt;
&lt;p&gt;There are two ways to specify a type:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;with its type name (Sample4.Count)&lt;/li&gt;
&lt;li&gt;with a generic type parameter (T.Count)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I was also proposing a way to specify a type for extension methods.&lt;/p&gt;
&lt;h2&gt;Where it would be useful - operators&lt;/h2&gt;
&lt;p&gt;The reason why everybody is asking for static members in interfaces is
ultimately to have &lt;strong&gt;operators&lt;/strong&gt; in interfaces.&lt;/p&gt;
&lt;p&gt;Imagine :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;interface&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IArithmetic&lt;/span&gt;&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; T &lt;span style="COLOR: blue"&gt;operator&lt;/span&gt; +(T x,
T y);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; T &lt;span style="COLOR: blue"&gt;operator&lt;/span&gt; -(T x,
T y);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; T &lt;span style="COLOR: blue"&gt;operator&lt;/span&gt; *(T x,
T y);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; T &lt;span style="COLOR: blue"&gt;operator&lt;/span&gt; /(T x,
T y);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Now you can write generic code like :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; T
Power&amp;lt;T&amp;gt;(&lt;span style="COLOR: blue"&gt;this&lt;/span&gt; T value, &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; count) &lt;span style="COLOR: blue"&gt;where&lt;/span&gt; T :
IArithmetic&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; result = T.Identity;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;for&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;int&lt;/span&gt;
i=0;i&amp;lt;count;i++)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
               
result = result*value;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; result;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Cool !&lt;/p&gt;
&lt;p&gt;This way, no need for the 20 overloads of Enumerable.Sum, it would work for
any type presenting the expected static interface.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=BiT44qCLfO4:Q-1adugHQTU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=BiT44qCLfO4:Q-1adugHQTU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=BiT44qCLfO4:Q-1adugHQTU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=BiT44qCLfO4:Q-1adugHQTU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=BiT44qCLfO4:Q-1adugHQTU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=BiT44qCLfO4:Q-1adugHQTU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=BiT44qCLfO4:Q-1adugHQTU:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=BiT44qCLfO4:Q-1adugHQTU:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/BiT44qCLfO4" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2009/10/22/CSharp-Static-interfaces-Take-2#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/453399</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2009/10/22/CSharp-Static-interfaces-Take-2</feedburner:origLink></entry>
    
  <entry>
    <title>C# Static interfaces</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/eSQz9dE2tSg/CSharp-Static-interfaces" rel="alternate" type="text/html" title="C# Static interfaces" />
    <id>urn:md5:8f2d85e4fd4e78398df3ed4b3ef3be1c</id>
    <updated>2009-10-21T14:46:00+02:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>.Net Framework</dc:subject>
        <dc:subject>.net</dc:subject><dc:subject>CSharp</dc:subject><dc:subject>Interfaces</dc:subject>    
    <content type="html">    &lt;p&gt;No DDD today, let’s talk a bit about our favorite language after a short
night (I should really tell my neighbors that 3am is not the good time to move
their furniture all around the flat).&lt;/p&gt;
&lt;p&gt;You can find requests for static methods in interfaces &lt;a href="http://dotnet.org.za/codingsanity/archive/2007/02/11/static-methods-on-interfaces.aspx" target="_blank"&gt;all&lt;/a&gt; &lt;a href="http://discuss.joelonsoftware.com/default.asp?dotnet.12.305680.12" target="_blank"&gt;over&lt;/a&gt; &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/1942d6ac-045f-42fc-8840-d83ef5d65bc7" target="_blank"&gt;the&lt;/a&gt; &lt;a href="http://p2p.wrox.com/c/18454-how-achieve-static-method-interface.html" target="_blank"&gt;internet&lt;/a&gt;..&lt;/p&gt;
&lt;p&gt;But there are good &lt;a href="http://blogs.msdn.com/ericlippert/archive/2007/06/14/calling-static-methods-on-type-variables-is-illegal-part-one.aspx" target="_blank"&gt;reasons&lt;/a&gt; &lt;a href="http://blogs.msdn.com/ericlippert/archive/2007/06/18/calling-static-methods-on-type-variables-is-illegal-part-two.aspx" target="_blank"&gt;not&lt;/a&gt; &lt;a href="http://blogs.msdn.com/ericlippert/archive/2007/06/21/calling-static-methods-on-type-variables-is-illegal-part-three.aspx" target="_blank"&gt;to&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;According to &lt;a href="http://blogs.msdn.com/ericlippert" target="_blank"&gt;Eric Lippert&lt;/a&gt;, the main reasons is the difference in inheritance
between static methods and instance method du to the absence of shared slots
between static methods.&lt;/p&gt;
&lt;p&gt;Mixing both static methods and instance methods in interfaces would lead to
a real nightmare when you try to understand what really happens.&lt;/p&gt;
&lt;p&gt;But why does this question arise so often then ? What’s really needed ?&lt;/p&gt;
&lt;h2&gt;Static classes as type instances&lt;/h2&gt;
&lt;p&gt;Let’s take a simple class with both static and instance members :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;class&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;Sample&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: green"&gt;// static part&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;int&lt;/span&gt; count;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;int&lt;/span&gt; Count { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; count; }
}&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: green"&gt;// instance part&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; name;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; Sample(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;
name) { &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.name = name; }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Method()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            count++;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="COLOR: #a31515"&gt;&amp;quot;Total
count {0} incremented by {1}&amp;quot;&lt;/span&gt;, count, name);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Here, Count is a static Property. Static part is different from instance
part in that static part exist only once per type.&lt;/p&gt;
&lt;p&gt;But we could see static part as being an object with reference is type
name.&lt;/p&gt;
&lt;p&gt;Why would these object not have interfaces ?&lt;/p&gt;
&lt;p&gt;Let refactor this a bit :&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Sample2&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;sealed&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Sample2Class&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; count;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; Count {
&lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt;
count; } }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Sample2Class&lt;/span&gt; Class = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Sample2Class&lt;/span&gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; name;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; Sample2(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;
name)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.name = name;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Method()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
           
Class.count++;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="COLOR: #a31515"&gt;&amp;quot;Total
count {0} incremented by {1}&amp;quot;&lt;/span&gt;, Class.count, name);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Here, the only static member is Class, that acts as a singleton for the
type. Note that I had to change the count modifier to internal. The behavior is
&lt;strong&gt;not&lt;/strong&gt; the same, but it’s conceptually equivalent.&lt;/p&gt;
&lt;p&gt;We can make something less extreme :&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Sample3&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;int&lt;/span&gt; count;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;int&lt;/span&gt; Count { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; count; }
}&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; name;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Sample3Class&lt;/span&gt; Class = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Sample3Class&lt;/span&gt;();&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;sealed&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Sample3Class&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; Count {
&lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt;
&lt;span style="COLOR: #2b91af"&gt;Sample3&lt;/span&gt;.Count; } }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; Sample3(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;
name) { &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.name = name; }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Method()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            count++;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="COLOR: #a31515"&gt;&amp;quot;Total
count {0} incremented by {1}&amp;quot;&lt;/span&gt;, count, name);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Here, we added only a proxy of public methods and properties on the
singleton class.&lt;/p&gt;
&lt;p&gt;We could define an interface that would be implemented by Sample3Class that
would provide the missing &lt;em&gt;slot&lt;/em&gt; concept that Eric Lipperts talk
about.&lt;/p&gt;
&lt;p&gt;We can also see here that there is no point mixing static and instance
method in interface since inheritance rules differs.&lt;/p&gt;
&lt;h2&gt;Static Interface&lt;/h2&gt;
&lt;p&gt;Imagination at work. Let’s define static interface as we can define static
classes :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;interface&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;ICountable&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; Count {
&lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;and implement it on our sample :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;    &lt;span style="COLOR: blue"&gt;public&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Sample4&lt;/span&gt; : ICountable&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;int&lt;/span&gt; count;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;int&lt;/span&gt; Count { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; count; }
}&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt;
&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; name;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; Sample4(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;
name) { &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.name = name; }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Method()&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            count++;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="COLOR: #a31515"&gt;&amp;quot;Total
count {0} incremented by {1}&amp;quot;&lt;/span&gt;, count, name);&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;    }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The C# compiler would be responsible for creating a singleton stub in the
class. Since the goal is to provide a function table, this could also be
handled at a lower level by the CLI.&lt;/p&gt;
&lt;p&gt;Now, we can have interesting language extensions.&lt;/p&gt;
&lt;h2&gt;Static member access in generics&lt;/h2&gt;
&lt;p&gt;Let see it in action :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt;
IsInstanciated&amp;lt;T&amp;gt;() &lt;span style="COLOR: blue"&gt;where&lt;/span&gt; T:
ICountable&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; T.Count != 0;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;There is no ambiguity when using this method since values of parameter T are
known at compilation time. The C# compiler could replace the static call with a
interface call on the proxy. On a CLI version, the JIT compiler could resolve
it once and for all and emit a static call. Use of a child type whose parent
type implements the interface should not be allowed, the compiler could report
this.&lt;/p&gt;
&lt;p&gt;This could be combined with an extension method syntax to provide extension
methods on types :&lt;/p&gt;
&lt;div style="BORDER-BOTTOM: #a0a0a0 1px solid; BORDER-LEFT: #a0a0a0 1px solid; FONT-FAMILY: courier new; BACKGROUND: #f8f8f8; COLOR: black; FONT-SIZE: 10pt; BORDER-TOP: #a0a0a0 1px solid; BORDER-RIGHT: #a0a0a0 1px solid"&gt;
&lt;p style="MARGIN: 0"&gt;        &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt;
IsInstanciated(&lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;ICountable&lt;/span&gt; type)&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        {&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;
            &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; type.Count != &lt;span style="COLOR: blue"&gt;0&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN: 0"&gt;        }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This one is a bit twisted, and I would gracefully admit changes in the
syntax, but the point is that it would enable on type/classes the same kind of
thing that Linq offers with interfaces : put the minimum set of methods in
interface, then add lots of features around interface with extension
methods.&lt;/p&gt;
&lt;h2&gt;Back to reality&lt;/h2&gt;
&lt;p&gt;Ok, I should sleep at night, but who knows, it’s perhaps useful.&lt;/p&gt;
&lt;p&gt;If anyone sees other applications… just drop a comment.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=eSQz9dE2tSg:fX14LUWF9Gs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=eSQz9dE2tSg:fX14LUWF9Gs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=eSQz9dE2tSg:fX14LUWF9Gs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=eSQz9dE2tSg:fX14LUWF9Gs:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=eSQz9dE2tSg:fX14LUWF9Gs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=eSQz9dE2tSg:fX14LUWF9Gs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=eSQz9dE2tSg:fX14LUWF9Gs:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=eSQz9dE2tSg:fX14LUWF9Gs:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/eSQz9dE2tSg" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2009/10/21/CSharp-Static-interfaces#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/453105</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2009/10/21/CSharp-Static-interfaces</feedburner:origLink></entry>
    
  <entry>
    <title>DDD and Code ReUse</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/rrCpuAquJNE/DDD-and-Code-ReUse" rel="alternate" type="text/html" title="DDD and Code ReUse" />
    <id>urn:md5:fd87018ee082bcf988197b20dea63976</id>
    <updated>2009-07-24T16:34:00+02:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>Domain Driven Design</dc:subject>
        <dc:subject>Design</dc:subject><dc:subject>Distributed Domain Driven Design</dc:subject><dc:subject>Domain Driven Design</dc:subject><dc:subject>Service Bus</dc:subject>    
    <content type="html">    &lt;p&gt;I read several discussions against Code ReUse and layered architectures
recently :&lt;a href="http://thinkbeforecoding.com/public/WindowsLiveWriter_DDDandCodeReuse_E89E_recycle-logo_2.jpg"&gt;&lt;img style="BORDER-BOTTOM: 0; BORDER-LEFT: 0; DISPLAY: inline; MARGIN-LEFT: 0; BORDER-TOP: 0; MARGIN-RIGHT: 0; BORDER-RIGHT: 0" title="recycle-logo" border="0" alt="recycle-logo" align="right" src="http://thinkbeforecoding.com/public/WindowsLiveWriter_DDDandCodeReuse_E89E_recycle-logo_thumb.jpg" width="195" height="253" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.udidahan.com/2009/06/07/the-fallacy-of-reuse/" target="_blank"&gt;The Fallacy Of ReUse&lt;/a&gt; (Udi Dahan) &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.vimeo.com/5022174" target="_blank"&gt;WebCast on SOA in
the E-VAN&lt;/a&gt; (Udi Dahan)&lt;/li&gt;
&lt;li&gt;&lt;a title="http://ayende.com/Blog/archive/2009/07/23/feature-by-feature.aspx" href="http://ayende.com/Blog/archive/2009/07/23/feature-by-feature.aspx" target="_blank"&gt;Feature by Feature&lt;/a&gt; (Oren Eini)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Different kinds of Code ReUse&lt;/h3&gt;
&lt;p&gt;You can split your code with different concern :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Object model extensions&lt;/li&gt;
&lt;li&gt;Technical Infrastructure&lt;/li&gt;
&lt;li&gt;Application code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first two are good candidates for Code ReUse.&lt;/p&gt;
&lt;p&gt;By Object model extensions I’m talking about things that make your code
writing less tedious at language level or object model level.&lt;/p&gt;
&lt;p&gt;Example of such code are :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IEnumerable and Enumerable&lt;/li&gt;
&lt;li&gt;Collections&lt;/li&gt;
&lt;li&gt;Reflection helpers&lt;/li&gt;
&lt;li&gt;Dependency Injection framework&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By Technical Infrastructure I mean things that make your code run in its
environment :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generic Service Host,&lt;/li&gt;
&lt;li&gt;ORM, Data Layer&lt;/li&gt;
&lt;li&gt;Format serializers / deserializers&lt;/li&gt;
&lt;li&gt;Configuration helpers&lt;/li&gt;
&lt;li&gt;Communication frameworks (WCF, Service Buses)&lt;/li&gt;
&lt;li&gt;UI frameworks (MVC, WPF)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The last part is Application code, and here, things are really
different.&lt;/p&gt;
&lt;h3&gt;Application Code ReUse&lt;/h3&gt;
&lt;p&gt;For long I’ve been writing business code in libraries. I began then to
notice problems concerning code and data locality.&lt;/p&gt;
&lt;p&gt;When you have a single application (process), no problem.&lt;/p&gt;
&lt;p&gt;But if two applications need to modify the same entities, the solution would
be to use the same library in both applications so that there is no code
duplication. It seems good practice but you quickly stumble on several problems
– I’m sure you already experienced it :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Synchronization : the same data will be accessed in the same db from two
application, how do you manage conflicts&lt;/li&gt;
&lt;li&gt;Deployment : when you fix bugs or add features, you must redeploy every
application that has a dependency on the library. It slows down the release
cycle and make it more risky, changes have more impact.&lt;/li&gt;
&lt;li&gt;Code locality : when a problem arises, you have to find which application
it comes from.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let’s examine DDD patterns to see how they fit with reuse :&lt;/p&gt;
&lt;h4&gt;Services&lt;/h4&gt;
&lt;p&gt;Let’s start easy. Services are stateless, they should deliver simple action.
But to preserve encapsulation the better is to put services as true services in
their own process (web service, windows service, service on a service
bus..).&lt;/p&gt;
&lt;p&gt;This way, synchronization is managed in process, deployment is a breeze, and
no problem with code locality – code executes in one place.&lt;/p&gt;
&lt;h4&gt;Entities&lt;/h4&gt;
&lt;p&gt;Entities are retrieved through a Repository Service, hence, they should
follow the same rules as Services.&lt;/p&gt;
&lt;p&gt;This way, the implementation of a repository that access the database is
truly an implementation details. Anyone who wants to talk to an entity sends a
command to it, a handler service get the entity from the repository, and pass
the command to the entity. The configuration to access the database is local
the to the process.&lt;/p&gt;
&lt;p&gt;Here again, same benefits.&lt;/p&gt;
&lt;p&gt;Moreover entities should always have different meanings in different bounded
contexts, the should have different implementations, so there is no real reason
for reuse.&lt;/p&gt;
&lt;h4&gt;Value Objects&lt;/h4&gt;
&lt;p&gt;Value objects are a bit different.&lt;/p&gt;
&lt;p&gt;Some object are very specific to a bounded context and don’t need to be
reuse outside.&lt;/p&gt;
&lt;p&gt;Some other can be a good way to encapsulate some shared concepts. Money is
usually a good example, but there can also be concepts more specific to the
domain (you will find them as words that come in the Ubiquitous Language of
different Bounded Contexts).&lt;/p&gt;
&lt;p&gt;They can be shared among different contexts, but rarely between different
domains. There are exceptions for very very generic concept like money, but
even money often needs to be tweaked a bit for each domain…&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;Service Bus to the rescue&lt;/h3&gt;
&lt;p&gt;Once each bounded context is split, you need to organize communications
between parts. Here comes the Service Bus and Messages, but now, the only
shared parts in the application are :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Object model extensions (to code faster and cleaner)&lt;/li&gt;
&lt;li&gt;Technical infrastructure (so that each process is fully equipped, and
there’s not much technical fuss in the application code)&lt;/li&gt;
&lt;li&gt;General use Value Objects (to manipulate domain concepts instead of int and
decimal)&lt;/li&gt;
&lt;li&gt;Messages (to communicate between contexts)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You could also use web services, but it makes the overall structure less
fault tolerant, harder to deploy, and more tightly coupled.&lt;/p&gt;
&lt;p&gt;Once you’ve decoupled bounded context using messages, the rest is just an
internal implementation detail, why would you want to reuse it !&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=rrCpuAquJNE:1DSWt0SXbz0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=rrCpuAquJNE:1DSWt0SXbz0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=rrCpuAquJNE:1DSWt0SXbz0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=rrCpuAquJNE:1DSWt0SXbz0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=rrCpuAquJNE:1DSWt0SXbz0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=rrCpuAquJNE:1DSWt0SXbz0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=rrCpuAquJNE:1DSWt0SXbz0:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=rrCpuAquJNE:1DSWt0SXbz0:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/rrCpuAquJNE" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2009/07/24/DDD-and-Code-ReUse#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/420748</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2009/07/24/DDD-and-Code-ReUse</feedburner:origLink></entry>
    
  <entry>
    <title>Distributed Domain Driven Design and Aggregates</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/spQQx40xhL0/Distributed-Domain-Driven-Design-and-Aggregates" rel="alternate" type="text/html" title="Distributed Domain Driven Design and Aggregates" />
    <id>urn:md5:9bf429b2b9fc59bd8fcda4797d5084f8</id>
    <updated>2009-06-23T16:59:00+02:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>Domain Driven Design</dc:subject>
        <dc:subject>DDD Exchange</dc:subject><dc:subject>Design</dc:subject><dc:subject>Distributed Domain Driven Design</dc:subject><dc:subject>Domain Driven Design</dc:subject>    
    <content type="html">    &lt;p&gt;Once again, Gojko Adzic comes with an excellent post : &lt;a href="http://gojko.net/2009/06/23/improving-performance-and-scalability-with-ddd/" target="_blank"&gt;Improving performance and scalability with DDD&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Aggregates are often a bit underused in DDD because they’re difficult to
grasp. They’re often seen as a solution to a technical problem. Gojko shows
here how to understand them at a domain level. This post gives a clear vision
of the role of Aggregates in DDD by placing it in the context of distributed
environments.&lt;/p&gt;
&lt;p&gt;You should read it !&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=spQQx40xhL0:WeL7Rnc6K0E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=spQQx40xhL0:WeL7Rnc6K0E:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=spQQx40xhL0:WeL7Rnc6K0E:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=spQQx40xhL0:WeL7Rnc6K0E:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=spQQx40xhL0:WeL7Rnc6K0E:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=spQQx40xhL0:WeL7Rnc6K0E:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=spQQx40xhL0:WeL7Rnc6K0E:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=spQQx40xhL0:WeL7Rnc6K0E:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/spQQx40xhL0" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2009/06/23/Distributed-Domain-Driven-Design-and-Aggregates#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/412868</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2009/06/23/Distributed-Domain-Driven-Design-and-Aggregates</feedburner:origLink></entry>
    
  <entry>
    <title>Where are my Entities and my Repositories ?</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/ONzvWwG3N-M/Where-are-my-Entities-and-my-Repositories" rel="alternate" type="text/html" title="Where are my Entities and my Repositories ?" />
    <id>urn:md5:6ae7d0a8dbe37bd7cec856a5e9e5ae8b</id>
    <updated>2009-06-23T14:20:00+02:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>Domain Driven Design</dc:subject>
            
    <content type="html">    &lt;p&gt;During &lt;a href="http://thinkbeforecoding.com/post/2009/06/16/Met-Eric-Evans-at-ParisJug" target="_blank"&gt;Evans’ talk at ParisJug&lt;/a&gt;, some attendees where surprised
that there was no mention of &lt;a href="http://dddstepbystep.com/wikis/ddd/entity.aspx" target="_blank"&gt;Entities&lt;/a&gt;
or &lt;a href="http://dddstepbystep.com/wikis/ddd/repository.aspx" target="_blank"&gt;Repositories&lt;/a&gt;…&lt;/p&gt;
&lt;p&gt;Quite a lot of people where introduced to Domain Driven Design by these
aspects and see these as the main advance of DDD.&lt;/p&gt;
&lt;p&gt;In contrast, Eric Evans explained to me he had some regrets he placed these
patterns so early in the book. Many readers think they know the most important
at this point and stop reading after chapter 6.&lt;/p&gt;
&lt;p&gt;Actually those patterns are only object model patterns that enable
Separation of Concerns and Persistence Ignorance, but can also be used in
context that are not Domain Driven at all like CRUD.&lt;/p&gt;
&lt;p&gt;Of course, if you want to implement a domain independent of all
infrastructure concerns, good OO practices will be required, but those
practices won’t make your application Domain Driven (don’t understand that not
following DDD would make your design a bad design… you apply DDD if you want
and if you need to, but achieving persistence ignorance won’t mean you practice
DDD.)&lt;/p&gt;
&lt;p&gt;But you’ve more to learn from Strategic Design, Bounded Contexts and
distillation of the Core Domain etc.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=ONzvWwG3N-M:gpN9ymyYgog:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=ONzvWwG3N-M:gpN9ymyYgog:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=ONzvWwG3N-M:gpN9ymyYgog:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=ONzvWwG3N-M:gpN9ymyYgog:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=ONzvWwG3N-M:gpN9ymyYgog:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=ONzvWwG3N-M:gpN9ymyYgog:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=ONzvWwG3N-M:gpN9ymyYgog:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=ONzvWwG3N-M:gpN9ymyYgog:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/ONzvWwG3N-M" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2009/06/23/Where-are-my-Entities-and-my-Repositories#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/412806</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2009/06/23/Where-are-my-Entities-and-my-Repositories</feedburner:origLink></entry>
    
  <entry>
    <title>Strategic Design at DDD Exchange</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/rLtmvcwFB1g/Strategic-Design-at-DDD-Exchange" rel="alternate" type="text/html" title="Strategic Design at DDD Exchange" />
    <id>urn:md5:1074642401ef925545fee70b306d04dd</id>
    <updated>2009-06-19T14:05:00+02:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>Domain Driven Design</dc:subject>
        <dc:subject>DDD Exchange</dc:subject><dc:subject>Design</dc:subject><dc:subject>Domain Driven Design</dc:subject><dc:subject>Evans</dc:subject><dc:subject>Strategic Design</dc:subject>    
    <content type="html">    &lt;p&gt;Gojko Adzik has a post about Eric Evans’ talk at &lt;a href="http://skillsmatter.com/event/design-architecture/ddd-exchange" target="_blank"&gt;DDD Exchange&lt;/a&gt; :&lt;/p&gt;
&lt;p&gt;&lt;a href="http://gojko.net/2009/06/19/eric-evans-why-do-efforts-to-replace-legacy-systems-fail/" target="_blank"&gt;Why do efforts to replace legacy system fail ?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can also read &lt;a href="http://thinkbeforecoding.com/post/2009/04/28/Strategic-Design" target="_blank"&gt;my previous post about strategic design&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I’m currently working on evolving a large legacy system, and my experience
tell me it’s the right way to deal with it !&lt;/p&gt;
&lt;p&gt;Don’t try to switch off legacy system. Go along with it using anticorruption
layers to protect you elegant core domain.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=rLtmvcwFB1g:3v-SIAXMf7U:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=rLtmvcwFB1g:3v-SIAXMf7U:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=rLtmvcwFB1g:3v-SIAXMf7U:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=rLtmvcwFB1g:3v-SIAXMf7U:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=rLtmvcwFB1g:3v-SIAXMf7U:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=rLtmvcwFB1g:3v-SIAXMf7U:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=rLtmvcwFB1g:3v-SIAXMf7U:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=rLtmvcwFB1g:3v-SIAXMf7U:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/rLtmvcwFB1g" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2009/06/19/Strategic-Design-at-DDD-Exchange#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/411792</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2009/06/19/Strategic-Design-at-DDD-Exchange</feedburner:origLink></entry>
    
  <entry>
    <title>Which model is best ? Thats not the question.</title>
    <link href="http://feeds.thinkbeforecoding.com/~r/ThinkBeforeCoding/~3/57DrjdN-wGw/Which-model-is-best-Thats-not-the-question" rel="alternate" type="text/html" title="Which model is best ? Thats not the question." />
    <id>urn:md5:6a3adb07c5dcf813857f3b8b18553125</id>
    <updated>2009-06-17T15:56:00+02:00</updated>
    <author><name>Jérémie Chassaing</name></author>
        <dc:subject>Domain Driven Design</dc:subject>
        <dc:subject>Design</dc:subject><dc:subject>Domain Driven Design</dc:subject><dc:subject>Evans</dc:subject><dc:subject>ParisJug</dc:subject>    
    <content type="html">    &lt;p&gt;&lt;a href="http://thinkbeforecoding.com/public/WindowsLiveWriter_Whatsthebestdesign_D516_Mercator_1569_1__2.png"&gt;
&lt;img style="BORDER-BOTTOM: 0; BORDER-LEFT: 0; MARGIN: 0 0 5px 15px; DISPLAY: inline; BORDER-TOP: 0; BORDER-RIGHT: 0" title="Mercator_1569" border="0" alt="Mercator_1569" align="right" src="http://thinkbeforecoding.com/public/WindowsLiveWriter_Whatsthebestdesign_D516_Mercator_1569_1__thumb.png" width="244" height="156" /&gt;&lt;/a&gt;Those who already read the book should already
know this. It’s still interesting for newcomers and you can  send comments
if you want !&lt;/p&gt;
&lt;p&gt;During his &lt;a href="http://thinkbeforecoding.com/post/2009/06/16/Met-Eric-Evans-at-ParisJug" target="_blank"&gt;Talk at ParisJug&lt;/a&gt;, Eric Evans presented two possible models
for Cargo itinerary.&lt;/p&gt;
&lt;p&gt;The first one was around the notion of Stops (at a Stop, you unload, then
you load), and the second one was around the notion of Legs(you load at the
start of a Leg, and unload at the end). An itinerary could be seen as a list of
stops or a list of legs.&lt;/p&gt;
&lt;p&gt;The question was, &lt;em&gt;which model is best&lt;/em&gt; ?&lt;/p&gt;
&lt;p&gt;Of course, there is no answer to this question.&lt;/p&gt;
&lt;p&gt;The same question was translated to a comparison of maps. First an map of
China from the 16th century, and a Mercator projection map.&lt;/p&gt;
&lt;p&gt;We should be inclined to say that the second one is best. But the first one
was largely enough for the need at that time. And if you inspect the Mercator
projection, you can notice that it is not that accurate for some tasks. For
example, the Greenland seems abnormally large.&lt;/p&gt;
&lt;p&gt;Why do we use Mercator projection then ?&lt;/p&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Mercator_projection" target="_blank"&gt;It became the standard map projection for nautical purposes because of
its ability to represent lines of constant course, known as rhumb lines or
loxodromes, as straight segments&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you want a map to compare country areas, use a &lt;a href="http://en.wikipedia.org/wiki/Gall-Peters_projection" target="_blank"&gt;Gall-Petters projection&lt;/a&gt; or a  &lt;a href="http://en.wikipedia.org/wiki/Goode_homolosine_projection" target="_blank"&gt;Goode homolosine projection&lt;/a&gt;…&lt;/p&gt;
&lt;p&gt;So the question becomes :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Which model is more useful ?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And for the question to be complete :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Which model is more useful for what ?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To come back to the cargo application, Stops will be useful to produce
orders to unload and reload containers from cargos, but legs will be useful if
you need to track transport location or change routing during transport.&lt;/p&gt;
&lt;p&gt;You’ll have noticed :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It depends on the context&lt;/p&gt;
&lt;/blockquote&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=57DrjdN-wGw:A7OML3LqQpY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=57DrjdN-wGw:A7OML3LqQpY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=57DrjdN-wGw:A7OML3LqQpY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=57DrjdN-wGw:A7OML3LqQpY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=57DrjdN-wGw:A7OML3LqQpY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=57DrjdN-wGw:A7OML3LqQpY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.thinkbeforecoding.com/~ff/ThinkBeforeCoding?a=57DrjdN-wGw:A7OML3LqQpY:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ThinkBeforeCoding?i=57DrjdN-wGw:A7OML3LqQpY:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThinkBeforeCoding/~4/57DrjdN-wGw" height="1" width="1"/&gt;</content>
    
    

    
          <wfw:comment>http://thinkbeforecoding.com/post/2009/06/17/Which-model-is-best-Thats-not-the-question#comment-form</wfw:comment>
      <wfw:commentRss>http://thinkbeforecoding.com/feed/atom/comments/410849</wfw:commentRss>
      <feedburner:origLink>http://thinkbeforecoding.com/post/2009/06/17/Which-model-is-best-Thats-not-the-question</feedburner:origLink></entry>
  
</feed>
