<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Domain Events &#8211; Take 2</title>
	<atom:link href="http://www.udidahan.com/2008/08/25/domain-events-take-2/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/</link>
	<description>Enterprise Development Expert &#38; SOA Specialist</description>
	<lastBuildDate>Thu, 11 Mar 2010 11:59:32 -0600</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Mike Chaliy</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-36934</link>
		<dc:creator>Mike Chaliy</dc:creator>
		<pubDate>Thu, 07 Jan 2010 11:17:40 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-36934</guid>
		<description>Hi there, I took an idea of the Domain Events and implemented it with Reactive Extensions API, take a look - http://chaliy.name/blog/2010/1/business_logic_rx_example</description>
		<content:encoded><![CDATA[<p>Hi there, I took an idea of the Domain Events and implemented it with Reactive Extensions API, take a look &#8211; <a href="http://chaliy.name/blog/2010/1/business_logic_rx_example" rel="nofollow">http://chaliy.name/blog/2010/1/business_logic_rx_example</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: udidahan</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-36783</link>
		<dc:creator>udidahan</dc:creator>
		<pubDate>Sun, 11 Oct 2009 08:49:10 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-36783</guid>
		<description>Mohammad,

Take a look at the next post in the series:

http://www.udidahan.com/2009/06/14/domain-events-salvation/

I hope that will clear things up for you.</description>
		<content:encoded><![CDATA[<p>Mohammad,</p>
<p>Take a look at the next post in the series:</p>
<p><a href="http://www.udidahan.com/2009/06/14/domain-events-salvation/" rel="nofollow">http://www.udidahan.com/2009/06/14/domain-events-salvation/</a></p>
<p>I hope that will clear things up for you.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mohammad Azam</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-36778</link>
		<dc:creator>Mohammad Azam</dc:creator>
		<pubDate>Sun, 11 Oct 2009 01:50:42 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-36778</guid>
		<description>Hi, 

I have been following this code for a couple of days and trying to understand some of the decision taken to reach this state. 

Why is AddGameToCartMessageHandler registering the events? Shouldn&#039;t the purpose of the Handler to handle the event instead of registering.

Thanks,
Azam</description>
		<content:encoded><![CDATA[<p>Hi, </p>
<p>I have been following this code for a couple of days and trying to understand some of the decision taken to reach this state. </p>
<p>Why is AddGameToCartMessageHandler registering the events? Shouldn&#8217;t the purpose of the Handler to handle the event instead of registering.</p>
<p>Thanks,<br />
Azam</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jimmy Zimms</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-36554</link>
		<dc:creator>Jimmy Zimms</dc:creator>
		<pubDate>Fri, 14 Aug 2009 00:59:39 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-36554</guid>
		<description>&gt;Neil Mosafi says: 
October 29, 2008 at 10:23 am
Not too keen on having the static global events, why not have the events defined as properties on the domain model? 

Neil,

The difference here is one of meaning. When you need to model an event occuring on the domain itself not any specific entity inside the domain you want to use this pattern. For example, an ObjectChanged event would be on a specific entity. A CustomerCreated event is on the domain itself. Basically the rule of thumb is to determine what makes more sense in the model: if the event argument is a value or an entity itself (or an identifier for the entity). When the former an instance event would make sense, the latter is on the domain itself with the entity being the args.</description>
		<content:encoded><![CDATA[<p>&gt;Neil Mosafi says:<br />
October 29, 2008 at 10:23 am<br />
Not too keen on having the static global events, why not have the events defined as properties on the domain model? </p>
<p>Neil,</p>
<p>The difference here is one of meaning. When you need to model an event occuring on the domain itself not any specific entity inside the domain you want to use this pattern. For example, an ObjectChanged event would be on a specific entity. A CustomerCreated event is on the domain itself. Basically the rule of thumb is to determine what makes more sense in the model: if the event argument is a value or an entity itself (or an identifier for the entity). When the former an instance event would make sense, the latter is on the domain itself with the entity being the args.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Domain Events - Salvation</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-36204</link>
		<dc:creator>Domain Events - Salvation</dc:creator>
		<pubDate>Sun, 14 Jun 2009 06:25:38 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-36204</guid>
		<description>[...] of success using the Domain Event pattern and the infrastructure I previously provided for it in Domain Events - Take 2. I&#8217;m happy to say that I&#8217;ve got an improvement that I think you&#8217;ll like. The main [...]</description>
		<content:encoded><![CDATA[<p>[...] of success using the Domain Event pattern and the infrastructure I previously provided for it in Domain Events &#8211; Take 2. I&#8217;m happy to say that I&#8217;ve got an improvement that I think you&#8217;ll like. The main [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Pete Grazaitis</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-36079</link>
		<dc:creator>Pete Grazaitis</dc:creator>
		<pubDate>Thu, 26 Mar 2009 18:28:40 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-36079</guid>
		<description>I have enjoyed using this model in my service layer.  However, I ran into an issue with static actions on the DomainEvent class.  

It is the case that I have multiple events that can be fired within the domain class.  In this case I have defined multiple DomainEvents but because the signature is the same, the static actions means that firing one event ultimately fires all event handlers.

Code:
DomainEvent NameChanged = new DomainEvent();
DomainEvent AddressChanged = new DomainEvent();
.
.
using(DomainEvents.NameChanged.Register(NameChangeHandler))
using(DomainEvents.AddressChanged.Register(AddressChangeHandler))
{
   person.Name = &quot;Pete&quot;;  //Fires Name change event.
   //Address Change not firing explicitly.
}
.
.
[ThreadStatic] 
private static List&lt;Action&gt; _actions; 

        public void Raise(E args) 
        {
            foreach (Action action in actions) 
                action.Invoke(args);
        }

NOTE: In this case both registered events are stored in the thread static actions shared by both DomainEvents of the type IPerson.  The result is that both NameChange and AddressChange handlers are called.

I simply dropped static altogether for my purposes.</description>
		<content:encoded><![CDATA[<p>I have enjoyed using this model in my service layer.  However, I ran into an issue with static actions on the DomainEvent class.  </p>
<p>It is the case that I have multiple events that can be fired within the domain class.  In this case I have defined multiple DomainEvents but because the signature is the same, the static actions means that firing one event ultimately fires all event handlers.</p>
<p>Code:<br />
DomainEvent NameChanged = new DomainEvent();<br />
DomainEvent AddressChanged = new DomainEvent();<br />
.<br />
.<br />
using(DomainEvents.NameChanged.Register(NameChangeHandler))<br />
using(DomainEvents.AddressChanged.Register(AddressChangeHandler))<br />
{<br />
   person.Name = &#8220;Pete&#8221;;  //Fires Name change event.<br />
   //Address Change not firing explicitly.<br />
}<br />
.<br />
.<br />
[ThreadStatic]<br />
private static List&lt;Action&gt; _actions; </p>
<p>        public void Raise(E args)<br />
        {<br />
            foreach (Action action in actions)<br />
                action.Invoke(args);<br />
        }</p>
<p>NOTE: In this case both registered events are stored in the thread static actions shared by both DomainEvents of the type IPerson.  The result is that both NameChange and AddressChange handlers are called.</p>
<p>I simply dropped static altogether for my purposes.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: udidahan</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-36027</link>
		<dc:creator>udidahan</dc:creator>
		<pubDate>Sun, 15 Feb 2009 15:47:26 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-36027</guid>
		<description>Daneil,

I&#039;m not quite sure I understand the solution you&#039;re proposing.</description>
		<content:encoded><![CDATA[<p>Daneil,</p>
<p>I&#8217;m not quite sure I understand the solution you&#8217;re proposing.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: udidahan</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-36026</link>
		<dc:creator>udidahan</dc:creator>
		<pubDate>Sun, 15 Feb 2009 09:27:19 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-36026</guid>
		<description>Evgeny,

Sounds interesting - I&#039;ll explore it.

Thanks.</description>
		<content:encoded><![CDATA[<p>Evgeny,</p>
<p>Sounds interesting &#8211; I&#8217;ll explore it.</p>
<p>Thanks.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Daniel Fernandes</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-36022</link>
		<dc:creator>Daniel Fernandes</dc:creator>
		<pubDate>Thu, 12 Feb 2009 11:41:39 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-36022</guid>
		<description>@Udi
That&#039;s an interesting idea of hosting the Domain in a different application domain in the context of a web application.
I guess Domain events could as well be reliabily implemented using internal messaging that queues up commands that need to be synchronously executed upon the end of a particular transaction, say post execution of a UI controller.</description>
		<content:encoded><![CDATA[<p>@Udi<br />
That&#8217;s an interesting idea of hosting the Domain in a different application domain in the context of a web application.<br />
I guess Domain events could as well be reliabily implemented using internal messaging that queues up commands that need to be synchronously executed upon the end of a particular transaction, say post execution of a UI controller.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Evgeny Shapiro</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-36010</link>
		<dc:creator>Evgeny Shapiro</dc:creator>
		<pubDate>Thu, 05 Feb 2009 16:31:40 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-36010</guid>
		<description>If you use NHibernate you can intercept the entities and catch the exceptions thrown in their methods. Then route the exceptions to the appropriate domain event handlers. This would remove the need for static events and enable you to use exceptions without the fear of accidentally treat a message as poisoned.

Generally you could introduce a meaningful exception type per event all deriving from a base type (let it be DomainException) and treat those exceptions as messages from the domain to the service layer. As before exceptions that are not derived from DomainException are either bugs or issues and not caught by the interceptor.

Another way is to introduce a disposable class DomainInteractionScope that would contain all the events you need to pass from the domain entities to the service layer. An instance of this class would be passed to the interceptor and would serve as an event container for single message handling. 

Also moving all this stuff to the container you would make the domain code much more clear (without the ugly if(...) { DomainEvents.(); return; } stuff).

Does that make sense? (c)</description>
		<content:encoded><![CDATA[<p>If you use NHibernate you can intercept the entities and catch the exceptions thrown in their methods. Then route the exceptions to the appropriate domain event handlers. This would remove the need for static events and enable you to use exceptions without the fear of accidentally treat a message as poisoned.</p>
<p>Generally you could introduce a meaningful exception type per event all deriving from a base type (let it be DomainException) and treat those exceptions as messages from the domain to the service layer. As before exceptions that are not derived from DomainException are either bugs or issues and not caught by the interceptor.</p>
<p>Another way is to introduce a disposable class DomainInteractionScope that would contain all the events you need to pass from the domain entities to the service layer. An instance of this class would be passed to the interceptor and would serve as an event container for single message handling. </p>
<p>Also moving all this stuff to the container you would make the domain code much more clear (without the ugly if(&#8230;) { DomainEvents.(); return; } stuff).</p>
<p>Does that make sense? (c)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: udidahan</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-35869</link>
		<dc:creator>udidahan</dc:creator>
		<pubDate>Wed, 24 Dec 2008 05:07:35 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-35869</guid>
		<description>Daniel,

Removing the [ThreadStatic] attribute causes a bug - an action on one thread by user A can call be into a different action previously registered by a different thread by user B.

The overall guidance is that the domain model with its associated events should not be called within the web app itself. Rather, the domain model should be hosted in its own process, an application server if you will, which the web app sends messages to.

Hope that helps.</description>
		<content:encoded><![CDATA[<p>Daniel,</p>
<p>Removing the [ThreadStatic] attribute causes a bug &#8211; an action on one thread by user A can call be into a different action previously registered by a different thread by user B.</p>
<p>The overall guidance is that the domain model with its associated events should not be called within the web app itself. Rather, the domain model should be hosted in its own process, an application server if you will, which the web app sends messages to.</p>
<p>Hope that helps.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Daniel Fernandes</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-35868</link>
		<dc:creator>Daniel Fernandes</dc:creator>
		<pubDate>Tue, 23 Dec 2008 09:44:01 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-35868</guid>
		<description>@Udi: There is a problem with [ThreadStatic] attribute with Web applications. 
I came across circumstances where the list of actions was null because I guess part of the HTTP request was handled by one thread and the rest by another one.
I&#039;ve removed this attribute and it&#039;s fine now.</description>
		<content:encoded><![CDATA[<p>@Udi: There is a problem with [ThreadStatic] attribute with Web applications.<br />
I came across circumstances where the list of actions was null because I guess part of the HTTP request was handled by one thread and the rest by another one.<br />
I&#8217;ve removed this attribute and it&#8217;s fine now.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: udidahan</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-35804</link>
		<dc:creator>udidahan</dc:creator>
		<pubDate>Sun, 02 Nov 2008 22:54:58 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-35804</guid>
		<description>Neil,

This creates extensibility and maintainability issues.

Suppose I write another domain object which acts as an aggregate root in a different scenario making use of the current parent as a child. I&#039;d have to remember to redefine that event on my object.

Does that make sense?</description>
		<content:encoded><![CDATA[<p>Neil,</p>
<p>This creates extensibility and maintainability issues.</p>
<p>Suppose I write another domain object which acts as an aggregate root in a different scenario making use of the current parent as a child. I&#8217;d have to remember to redefine that event on my object.</p>
<p>Does that make sense?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Neil Mosafi</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-35790</link>
		<dc:creator>Neil Mosafi</dc:creator>
		<pubDate>Wed, 29 Oct 2008 16:23:33 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-35790</guid>
		<description>Not too keen on having the static global events, why not have the events defined as properties on the domain model?  I know you would say &quot;but what if a child object raised the event?&quot; but I would say that&#039;s the parent object&#039;s responsibility to listen to child object events and either handle them or raise its own events accordingly (or simply delegate via a custom add and remove handler).

What would be the problem with that?</description>
		<content:encoded><![CDATA[<p>Not too keen on having the static global events, why not have the events defined as properties on the domain model?  I know you would say &#8220;but what if a child object raised the event?&#8221; but I would say that&#8217;s the parent object&#8217;s responsibility to listen to child object events and either handle them or raise its own events accordingly (or simply delegate via a custom add and remove handler).</p>
<p>What would be the problem with that?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: How to create fully encapsulated Domain Models</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-31508</link>
		<dc:creator>How to create fully encapsulated Domain Models</dc:creator>
		<pubDate>Wed, 10 Sep 2008 20:19:57 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-31508</guid>
		<description>[...] Update: The new and improved solution is now available: Domain Events, Take 2. [...]</description>
		<content:encoded><![CDATA[<p>[...] Update: The new and improved solution is now available: Domain Events, Take 2. [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: udidahan</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-31120</link>
		<dc:creator>udidahan</dc:creator>
		<pubDate>Sat, 06 Sep 2008 08:46:26 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-31120</guid>
		<description>Ayende,

There is (kinda) support for that in the handling of the MessageReceived event of the transport - by setting the order of subscriptions you can do Before and After handling.</description>
		<content:encoded><![CDATA[<p>Ayende,</p>
<p>There is (kinda) support for that in the handling of the MessageReceived event of the transport &#8211; by setting the order of subscriptions you can do Before and After handling.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ayende Rahien</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-30822</link>
		<dc:creator>Ayende Rahien</dc:creator>
		<pubDate>Thu, 04 Sep 2008 05:46:25 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-30822</guid>
		<description>You need to support the concept of IMessageModule, not just IMessageHandler.</description>
		<content:encoded><![CDATA[<p>You need to support the concept of IMessageModule, not just IMessageHandler.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: udidahan</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-30522</link>
		<dc:creator>udidahan</dc:creator>
		<pubDate>Mon, 01 Sep 2008 22:05:19 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-30522</guid>
		<description>Ayende,

It&#039;s actually possible to have another message handler run at the end of the unit of work and do the clean-up for that thread.

Still thinking about the generality of that solution.</description>
		<content:encoded><![CDATA[<p>Ayende,</p>
<p>It&#8217;s actually possible to have another message handler run at the end of the unit of work and do the clean-up for that thread.</p>
<p>Still thinking about the generality of that solution.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: udidahan</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-30454</link>
		<dc:creator>udidahan</dc:creator>
		<pubDate>Mon, 01 Sep 2008 06:56:14 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-30454</guid>
		<description>Tony,

I consider having the service layer use the result of one call to the domain to decide if another call to the domain is necessary to be taking domain logic out of the domain. 

In your example, I would prefer a single call:

cart.Add(game, policies);

The question is about the connection between the domain and the policies - what are the dependencies between them, how did the service layer get an instance of it, etc.</description>
		<content:encoded><![CDATA[<p>Tony,</p>
<p>I consider having the service layer use the result of one call to the domain to decide if another call to the domain is necessary to be taking domain logic out of the domain. </p>
<p>In your example, I would prefer a single call:</p>
<p>cart.Add(game, policies);</p>
<p>The question is about the connection between the domain and the policies &#8211; what are the dependencies between them, how did the service layer get an instance of it, etc.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tony Chevis</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-30425</link>
		<dc:creator>Tony Chevis</dc:creator>
		<pubDate>Mon, 01 Sep 2008 00:54:25 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-30425</guid>
		<description>Udi,

Maybe you should inject policies into the Cart. The policies are services which perform the checking. Just because the services live outside the domain doesn&#039;t mean the domain is anemic. After all, you are adding intelligence to the domain and can do so using your IoC container.

The service code would look something like:

cart.enforcePolicies(GameOrderPolicies);
if (cart.canAddGame(game))
   cart.add(game);
else
   Bus.return(cart.brokenPolicies[0].PolicyName)

Your domain only knows that there are certain policies which will be injected in, and those policies must be compliant before before adding a game.</description>
		<content:encoded><![CDATA[<p>Udi,</p>
<p>Maybe you should inject policies into the Cart. The policies are services which perform the checking. Just because the services live outside the domain doesn&#8217;t mean the domain is anemic. After all, you are adding intelligence to the domain and can do so using your IoC container.</p>
<p>The service code would look something like:</p>
<p>cart.enforcePolicies(GameOrderPolicies);<br />
if (cart.canAddGame(game))<br />
   cart.add(game);<br />
else<br />
   Bus.return(cart.brokenPolicies[0].PolicyName)</p>
<p>Your domain only knows that there are certain policies which will be injected in, and those policies must be compliant before before adding a game.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Chris Ortman</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-29984</link>
		<dc:creator>Chris Ortman</dc:creator>
		<pubDate>Tue, 26 Aug 2008 02:00:25 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-29984</guid>
		<description>I like this much better than the first.
Here&#039;s a few things that come to mind that might be nice from a public api perspective

1) conventions++ 
    using(DomainEvents.Register(cartIsFull, gameIsLost)) {

    }

   I /think/ we can parse out the variable name using the C# 3.0 Expression stuff.

2) using.... the ability of returning something like IDisposableAction is great, but unless there&#039;s great readability to be gained I don&#039;t think I&#039;m in favor of using using this way, is it that much better than something like With.Events(() =&gt; {    });</description>
		<content:encoded><![CDATA[<p>I like this much better than the first.<br />
Here&#8217;s a few things that come to mind that might be nice from a public api perspective</p>
<p>1) conventions++<br />
    using(DomainEvents.Register(cartIsFull, gameIsLost)) {</p>
<p>    }</p>
<p>   I /think/ we can parse out the variable name using the C# 3.0 Expression stuff.</p>
<p>2) using&#8230;. the ability of returning something like IDisposableAction is great, but unless there&#8217;s great readability to be gained I don&#8217;t think I&#8217;m in favor of using using this way, is it that much better than something like With.Events(() =&gt; {    });</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ayende Rahien</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-29977</link>
		<dc:creator>Ayende Rahien</dc:creator>
		<pubDate>Mon, 25 Aug 2008 23:58:13 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-29977</guid>
		<description>But that is something that should be in the infrastructure.
You put &quot;clean domain events&quot; as part of the life cycle.
Putting it in the code means that you have concerns in your code that the infrastructure should handle.</description>
		<content:encoded><![CDATA[<p>But that is something that should be in the infrastructure.<br />
You put &#8220;clean domain events&#8221; as part of the life cycle.<br />
Putting it in the code means that you have concerns in your code that the infrastructure should handle.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: udidahan</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-29956</link>
		<dc:creator>udidahan</dc:creator>
		<pubDate>Mon, 25 Aug 2008 19:20:45 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-29956</guid>
		<description>Ayende,

The problem with weakrefs, it turns out, is that the thread may run fast enough that garbage colleciton doesn&#039;t occur in time. As such, we may have a dangling delegate being activated from the handling of a previous message by the same thread.

That&#039;s why I need scoping - to simplify cleanup.</description>
		<content:encoded><![CDATA[<p>Ayende,</p>
<p>The problem with weakrefs, it turns out, is that the thread may run fast enough that garbage colleciton doesn&#8217;t occur in time. As such, we may have a dangling delegate being activated from the handling of a previous message by the same thread.</p>
<p>That&#8217;s why I need scoping &#8211; to simplify cleanup.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ayende Rahien</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/comment-page-1/#comment-29942</link>
		<dc:creator>Ayende Rahien</dc:creator>
		<pubDate>Mon, 25 Aug 2008 14:15:16 +0000</pubDate>
		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/#comment-29942</guid>
		<description>You can change this:
 this.CallOnDispose.DynamicInvoke();
to this:
 this.CallOnDispose();

And get the same behavior with static invocation.
Same for the Raise() method.

Do you really need scoping in here? Why not support this syntax?

public class AddGameToCartMessageHandler :
    BaseMessageHandler
{
    public override void Handle(AddGameToCartMessage m)
    {
		 DomainEvents.GameReportedLost+= delegate{
     Bus.Return((int)ErrorCoes.GameReportedLost); 
};
DomainEvents.CartIsFull += delegate{
    Bus.Return((int)ErrorCodes.CartIsFull);
};

       using (ISession session = SessionFactory.OpenSession())
        using (ITransaction tx = session.BeginTransaction())
        using (.Register(cartIsFull))
        {
            ICart cart = session.Get(m.CartId);
            IGame g = session.Get(m.GameId);
 
            cart.Add(g);
 
            tx.Commit();
        }
    }
 
}</description>
		<content:encoded><![CDATA[<p>You can change this:<br />
 this.CallOnDispose.DynamicInvoke();<br />
to this:<br />
 this.CallOnDispose();</p>
<p>And get the same behavior with static invocation.<br />
Same for the Raise() method.</p>
<p>Do you really need scoping in here? Why not support this syntax?</p>
<p>public class AddGameToCartMessageHandler :<br />
    BaseMessageHandler<br />
{<br />
    public override void Handle(AddGameToCartMessage m)<br />
    {<br />
		 DomainEvents.GameReportedLost+= delegate{<br />
     Bus.Return((int)ErrorCoes.GameReportedLost);<br />
};<br />
DomainEvents.CartIsFull += delegate{<br />
    Bus.Return((int)ErrorCodes.CartIsFull);<br />
};</p>
<p>       using (ISession session = SessionFactory.OpenSession())<br />
        using (ITransaction tx = session.BeginTransaction())<br />
        using (.Register(cartIsFull))<br />
        {<br />
            ICart cart = session.Get(m.CartId);<br />
            IGame g = session.Get(m.GameId);<br />
 <br />
            cart.Add(g);<br />
 <br />
            tx.Commit();<br />
        }<br />
    }<br />
 <br />
}</p>
]]></content:encoded>
	</item>
</channel>
</rss>
