﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2021 (c) 2026</copyright><ttl>60</ttl><item><title>Udi Dahan commented on Re: How to create fully encapsulated Domain Models</title><description>It sounds to me like fraud detection is something that should happen  in multiple parts of the system - preferably before the actual action happens - ie transferring money. That is a domain type cross cutting concern.
  
  
Your assumption that you added something to the domain that NEEDS to be handled is a design choice that seems to be creating problems. I would choose a different design.
  
  
In terms of testing, these kinds of issues are tested for in end-to-end testing.
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment22</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment22</guid><pubDate>Sat, 05 Apr 2008 08:55:56 GMT</pubDate></item><item><title>Ayende Rahien commented on Re: How to create fully encapsulated Domain Models</title><description>I am not talking about adding cross cutting concern. I am talking about changing the current business process and wanting it to be _broken_ until it is fixed across the board.
  
Yes, waiting for production to catch this is about as bad as it can get, that is why I want it to be _broken_, not silently ignoring the change.
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment21</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment21</guid><pubDate>Mon, 31 Mar 2008 06:34:40 GMT</pubDate></item><item><title>Udi Dahan commented on Re: How to create fully encapsulated Domain Models</title><description>"Assume that you added something to the domain, something that requires handling."
  
  
From my experience, that assumption cannot be upheld in larger team environments. That family of problems is handled by intercepting message handlers. It is a separation of concerns issue. This side-steps the issue of the domain having to roll itself back without causing the system to crash.
  
  
To me, it doesn't make sense that you'd have to push something into production to find that failing - design and code reviews make sure that the domain doesn't assume more responsibility than it should.
  
  
I prefer a design that elegantly steps around the big hard problems at the cost of a little typing - but you already know that.
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment20</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment20</guid><pubDate>Mon, 31 Mar 2008 06:16:16 GMT</pubDate></item><item><title>Ayende Rahien commented on Re: How to create fully encapsulated Domain Models</title><description>It answers the wrong question, I am afraid.
  
Assume that you added something to the domain, something that requires handling. My approach ensures that it will be handled. If only because all messages would fail when it is pushed to production.
  
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment19</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment19</guid><pubDate>Sun, 30 Mar 2008 15:05:54 GMT</pubDate></item><item><title>Udi Dahan commented on Re: How to create fully encapsulated Domain Models</title><description>I have more than one message handler that handles the BankTransactionMessage - I have one BankTransactionMessageHandler (BTMH), and another FraudDetectionMessageHandler (FDMH) - which is configured to run before all other handlers.
  
  
If the FDMH detects a fraud, it takes the appropriate action as well as calling:
  
  
this.Bus.DoNotContinueDispatchingCurrentMessageToHandlers();
  
  
which will prevent the BTMH from running at all. In this way, there is no need to undo any actions that the domain may have taken, because it may not even have been called at all.
  
  
Does that make sense?
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment18</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment18</guid><pubDate>Sun, 30 Mar 2008 14:24:35 GMT</pubDate></item><item><title>Ayende Rahien commented on Re: How to create fully encapsulated Domain Models</title><description>I am not following, are you saying that you would detect something like that anyway? I am not sure that I see how
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment17</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment17</guid><pubDate>Sun, 30 Mar 2008 13:36:21 GMT</pubDate></item><item><title>Udi Dahan commented on Re: How to create fully encapsulated Domain Models</title><description>Those cases are done with intercepting message handlers. While you might use the same domain model in your FraudDetectionMessageHandler, you can choose some other way to do that as well.
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment16</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment16</guid><pubDate>Sun, 30 Mar 2008 13:25:50 GMT</pubDate></item><item><title>Ayende Rahien commented on Re: How to create fully encapsulated Domain Models</title><description>The problem with that is that I lose the fail as early as possible semantics, which are important for healthy system.
  
Let us say that we add an event for SuspectedFraud, and we aren't handling that in this message handler. Is it valid for it to keep on going?
  
I prefer it to fail, get the admin to notice that and hit me on the head for not fixing the message handlers when I added this.
  
The other approach would detect the fraud and do nothing with it.
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment15</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment15</guid><pubDate>Sun, 30 Mar 2008 10:42:25 GMT</pubDate></item><item><title>Udi Dahan commented on Re: How to create fully encapsulated Domain Models</title><description>"What we can't see is that an attempt from the domain model to call a delegate that wasn't registered would raise an error. I don't believe in ignoring errors."
  
  
That's just it - it's not an error, per se. It's the domain model's way of letting you know what it thinks. If you don't care about certain things, for instance, because you don't have a way to let the client know about it, or because the domain added an event you don't know about - why should that cause your system to break?
  
  
Believe me, you don't want that hidden coupling.
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment14</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment14</guid><pubDate>Sun, 30 Mar 2008 09:36:24 GMT</pubDate></item><item><title>Udi Dahan commented on Re: How to create fully encapsulated Domain Models</title><description>"What are the roles of services using this model?"
  
  
None. They are handled outside the Domain Model.
  
  
"As a simple example, when new user is created, we should send a welcome email."
  
  
The domain objects would raise an event saying that user should be welcomed. Service Layer takes that event and sends a business message (WelcomeUserMessage) copying into it all relevant information from the domain.
  
  
The WelcomeUserMessage gets sent to an endpoint which knows that that involves email, builds an email from a template, and uses SMTP to send it out.
  
  
Failure modes of email and of the original use case (create user) are very different. At a snapshot in time, one can be successful whereas the other could have failed, and that's a consistent view that need not be kept isolated.
  
  
When using this design, we find that our OLTP performance is independent of SMTP performance, and vice versa - we're better set up to do batch email sending. 
  
  
In other words, we get a more robust and performant solution once we get those external services out of the domain...
  
  
Sign here, on the dotted line :-)
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment13</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment13</guid><pubDate>Fri, 28 Mar 2008 22:26:38 GMT</pubDate></item><item><title>Colin Jack commented on Re: How to create fully encapsulated Domain Models</title><description>@Derick
  
Can't agree really, I know Ayende is not a fan of sections of the book but I think the Framework Design Guidelines are about right regarding exceptions. As you say though the cost which can't be ignored but not using them for control flow is a general principle anyway, vaguely remember reading about the cost some time ago but 5-10 seconds seems like something odd was going on?
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment12</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment12</guid><pubDate>Thu, 27 Mar 2008 13:04:53 GMT</pubDate></item><item><title>Derick Bailey commented on Re: How to create fully encapsulated Domain Models</title><description>I prefer the OperationResult return values over exceptions for a lot of reasons. Primarily, it makes development easier for me, as a user of an API, because i do not have to magically know which exceptions may be thrown and what fields on those exceptions to check, to find out why the exception was thrown and how to recover. 
  
  
in the world of Java, we have checked exceptions - every method that can thrown an exception has to state that is can, so our code is forced to account for that exception. in .NET, exceptions are truly for exceptional situations - when something CANNOT continue processing. think of them as the blue screen of death for your code. 
  
  
on top of that, throwing exceptions is horrendously expensive compared to building an OperationResult object with values to express the issues that occured. I've seen debuggers step through exception throwing / handling, and take 5 to 10 seconds to find the correct exception handler, whereas creating an operating result is typically subsecond - as fast as you can click the step through button.
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment11</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment11</guid><pubDate>Tue, 25 Mar 2008 21:09:14 GMT</pubDate></item><item><title>Ayende Rahien commented on Re: How to create fully encapsulated Domain Models</title><description>Yes, in a short while
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment10</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment10</guid><pubDate>Mon, 24 Mar 2008 20:09:00 GMT</pubDate></item><item><title>Craig Neuwirt commented on Re: How to create fully encapsulated Domain Models</title><description>Great stuff!!
  
  
Any plans on integrating the FutureQueryOf with Rhino Common IRepository?
  
  
craig
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment9</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment9</guid><pubDate>Mon, 24 Mar 2008 19:44:49 GMT</pubDate></item><item><title>Josh commented on Re: How to create fully encapsulated Domain Models</title><description>Irrelevant minor fix:
  
Future&lt;TradeInCart&gt; g = gamesRepository.GetFuture&lt;Game&gt;(m.GameId); 
  
  
should be
  
  
Future&lt;Game&gt; g = gamesRepository.GetFuture&lt;Game&gt;(m.GameId); 
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment8</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment8</guid><pubDate>Mon, 24 Mar 2008 18:00:05 GMT</pubDate></item><item><title>Ayende Rahien commented on Re: How to create fully encapsulated Domain Models</title><description>OperationResult == the return value of the method, which can be used to stored all the validation, errors, etc.
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment7</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment7</guid><pubDate>Mon, 24 Mar 2008 10:13:20 GMT</pubDate></item><item><title>Ayende Rahien commented on Re: How to create fully encapsulated Domain Models</title><description>Colin,
  
re: TypeMock - Yes, I find this amusing as well.
  
  
re: Exceptions - I am not 100% convinced, but I think that it makes a lot of sense.
  
I might go with an OperationResult instead, but it is basically the same idea.
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment6</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment6</guid><pubDate>Mon, 24 Mar 2008 10:12:22 GMT</pubDate></item><item><title>Udi Dahan commented on Re: How to create fully encapsulated Domain Models</title><description>Shawn,
  
  
The main problem comes when you have this occuring in the context of handling a message - server side. 
  
  
In order for the system to be robust, as in not lose messages when bad things (like server crashes) happen, then the receipt of the message from the queue and the DB transaction need to roll forwards and back together. This also includes sending of messages - rolling back means messages should NOT be sent, as the original message will be handled again.
  
  
In short, you can't/shouldn't count on sending an error message back to the client when rolling back.
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment5</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment5</guid><pubDate>Mon, 24 Mar 2008 08:34:21 GMT</pubDate></item><item><title>Colin Jack commented on Re: How to create fully encapsulated Domain Models</title><description>@Ayende
  
Are exceptions really completely unsuitable? In general I think they are a more natural way of reporting errors than events/callbacks.
  
  
Oh and I just had a "TypeMock" advert at the right hand side in the "Lounge" area :)
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment4</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment4</guid><pubDate>Mon, 24 Mar 2008 08:18:55 GMT</pubDate></item><item><title>Andreas commented on Re: How to create fully encapsulated Domain Models</title><description>How would the client code look in your example? 
  
  
I guess I timeout would be used to give the user the "a Technical Error has occured" dialog if the processing takes to long?
  
  
And finally, I think you have a bug in your "in-brain" compiler:
  
  
 Future&lt;TradeInCart&gt; g = gamesRepository.GetFuture&lt;Game&gt;(m.GameId); 
  
 should be:
  
 Future&lt;Game&gt; g = gamesRepository.GetFuture&lt;Game&gt;(m.GameId); 
  
  
:)
  
  
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment3</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment3</guid><pubDate>Mon, 24 Mar 2008 07:02:18 GMT</pubDate></item><item><title>Ayende Rahien commented on Re: How to create fully encapsulated Domain Models</title><description>Shawn,
  
Oh, it is feasible all right. That is not the issue.
  
The issue is whatever this is the right thing to do.
  
As I said in the post, I can make arguments for both cases
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment2</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment2</guid><pubDate>Mon, 24 Mar 2008 06:55:33 GMT</pubDate></item><item><title>Shawn Neal commented on Re: How to create fully encapsulated Domain Models</title><description>When a domain error is encountered, what about letting the transaction rollback and then send a failure message (separate from return error code)?  If there's a handler listening for the "CannotAddStolenGameMessage" that would be your alert, which If I understand this correctly would be in a separate transaction.
  
  
I haven't played around with NServiceBus enough to know if thats feasible  or sensible.
</description><link>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment1</link><guid>http://ayende.com/3209/re-how-to-create-fully-encapsulated-domain-models#comment1</guid><pubDate>Mon, 24 Mar 2008 05:07:16 GMT</pubDate></item></channel></rss>