<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Udi Dahan - The Software Simplist &#187; Development</title>
	<atom:link href="http://www.udidahan.com/category/development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.udidahan.com</link>
	<description>Enterprise Development Expert &#38; SOA Specialist</description>
	<lastBuildDate>Sat, 24 Jul 2010 20:06:18 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Evolving Loosely-Coupled Frameworks &amp; Apps</title>
		<link>http://www.udidahan.com/2010/07/14/evolving-loosely-coupled-frameworks-and-apps/</link>
		<comments>http://www.udidahan.com/2010/07/14/evolving-loosely-coupled-frameworks-and-apps/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 13:10:18 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Dependency Injection]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[NServiceBus]]></category>
		<category><![CDATA[OO]]></category>
		<category><![CDATA[Simplicity]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1312</guid>
		<description><![CDATA[This post will be less of a big-concept type posts I usually do, and more of a tip for people building and maintaining infrastructure and frameworks either open-source or internally for their companies. I&#8217;m going to illustrate this with NServiceBus as it is a large enough code base to have significant complexity and open so [...]]]></description>
			<content:encoded><![CDATA[<p>This post will be less of a big-concept type posts I usually do, and more of a tip for people building and maintaining infrastructure and frameworks either open-source or internally for their companies. I&#8217;m going to illustrate this with NServiceBus as it is a large enough code base to have significant complexity and open so that you can go and take a look yourself. Trying to include some example in here would be just too small to be useful or for the point to come across.</p>
<h3>Some background</h3>
<p>As a cohesive framework, NServiceBus makes it quite easy for developers to pick and choose which settings they want turned on and off. Being built as a loosely-coupled set of components that don&#8217;t know about each other has always kept the internal complexity low. But as the NServiceBus API has been evolving over the years, and the functionality offered has increased, some interesting challenges have popped up as the codebase has been refactored. </p>
<h3>The challenge</h3>
<p>The UnicastBus class has grown too large and it&#8217;s time to refactor something out. Coincidentally, users have been asking for a better &#8220;header&#8221; story for messages &#8211; the ability to specify static headers that will be appended to all messages being sent (useful for things like security tokens), as well as per message headers. So, we want to refactor all the header management out to its own component independent of the UnicastBus class.</p>
<p>So, here&#8217;s the issue. So far, users have specified &#8220;.UnicastBus()&#8221; as a part of the fluent code-configuration, and shouldn&#8217;t have to change that &#8211; they shouldn&#8217;t need to know that header management is now a separate component. But then how can the new component bootstrap itself into the startup, such that it gets all the dependency injection facilities of the rest of the framework? Remember that the component doesn&#8217;t know which container technology is being used (since the user can swap it out) or when the container has been set.</p>
<h3>The solution</h3>
<p>The only part of the framework that knows about when all DI configuration is set is the configuration component, thus it will have to be the one that invokes the new component (without knowing about it). Introduce an interface (say INeedInitialization) and scan all the types loaded looking for classes which implement that type, register them into the container, and invoke them. Have the new component implement that interface, and in its initialization have it hook into the events and/or pipelines of other parts of the system.</p>
<h3>Other uses</h3>
<p>One historically problematic area in NServiceBus has been people forgetting to call &#8220;.LoadMessageHandlers()&#8221;. This can now be wired in automatically by a class in the UnicastBus component via the same mechanism.</p>
<p>A new feature coming in the next version is the &#8220;data bus&#8221;, a component which will allow sending large quantities of data through the bus without going through the messaging pipelines. This will help people get around the 4MB limit of MSMQ and, even more importantly, the much smaller 8KB limit of Azure. We will be able to introduce the functionality transparently with the same mechanism.</p>
<p>As an extension point, developers can now enrich the NServiceBus framework with their own capabilities and make those available via the contrib project to the community at large. This is better than the IWantToRunAtStartup interface that was only available for those using the generic host (which excluded web apps) and gives a consistent extensibility story for all uses.</p>
<h3>Summary</h3>
<p>Extensibility has always been a challenge when writing object-oriented code and dependency injection techniques have helped, but sometimes you need a bit more to take things to the next level while maintaining a backwards-compatible API.</p>
<p>Like I said, not a ground-shaking topic but something quite necessary in creating loosely-coupled frameworks and applications. Once you know it&#8217;s there, it isn&#8217;t really a big deal. If you didn&#8217;t know to do it, you may have been contorting your codebase in all kinds of ways to try to achieve similar things.</p>
<p>If you want to take a look at the code, you can find the SVN repository here: https://nservicebus.svn.sourceforge.net/svnroot/nservicebus/trunk/</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2010/07/14/evolving-loosely-coupled-frameworks-and-apps/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Server Naming and Configuration Conflicts</title>
		<link>http://www.udidahan.com/2010/06/05/server-naming-and-configuration-conflicts/</link>
		<comments>http://www.udidahan.com/2010/06/05/server-naming-and-configuration-conflicts/#comments</comments>
		<pubDate>Sat, 05 Jun 2010 12:59:13 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Simplicity]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1289</guid>
		<description><![CDATA[In my work with clients the topic of how to handle the movement of software from one environment to another inevitably comes up. Sometimes this is in the context of NServiceBus but the problem is more generic. The faster that an organization is able to get software out the door, the more agile they can [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/Configuration_icon_by_obsilion.png" alt="Configuration" title="Configuration" width="225" height="221" style="float:right;" />In my work with clients the topic of how to handle the movement of software from one environment to another inevitably comes up. Sometimes this is in the context of NServiceBus but the problem is more generic. The faster that an organization is able to get software out the door, the more agile they can be. </p>
<p>Unfortunately, there is one tiny little mistake that I see almost everywhere that gets in the way, and that&#8217;s going to be the topic of this post.</p>
<h3>The Problem</h3>
<p>Let&#8217;s say you have a standard web app environment &#8211; some web servers, application servers, and a database server. Your web servers need to send messages to the application servers. So far, so good.</p>
<p>In your test environment, you have an application server called AS_01_Test, and your web servers are configured to send it messages. However, in your staging environment the application server fulfilling that same role is called AS_01_Stage. This creates a configuration problem &#8211; you need to change the config of your web servers as you move the web app from Test to Staging.</p>
<p>I&#8217;ve seen companies doing all sorts of creative things to get around this problem &#8211; some of them involve putting all configuration settings in a database so that they can be centrally managed and visualized. I&#8217;d like to suggest an alternative approach.</p>
<h3>What if&#8230;</h3>
<p>What if server names were the same across all environments?</p>
<p>Well, you wouldn&#8217;t need to change configuration as you moved the system between environments. That&#8217;s a good thing.</p>
<p>But how can that be? Wouldn&#8217;t there be a conflict if there were two machines with the same name?</p>
<p>The answer is that there wouldn&#8217;t be a conflict if the machines were on different networks. Not all machines have to be on the same network. We can set up as many networks / virtual networks as we like. And it is clear that we don&#8217;t need machines in one environment / network to talk to machines in another environment. I mean, under no circumstances would we want web servers in our test environment to talk to application servers in the production environment.</p>
<p>These separate networks provide much needed isolation, beyond solving the server naming problem.</p>
<h3>In closing</h3>
<p>It&#8217;s really a tiny thing when you think about &#8211; multiple networks. But that&#8217;s exactly why software developers overlook it so often &#8211; because it&#8217;s not a &#8220;software solution&#8221; to the configuration problem we perceive as a &#8220;software problem&#8221;.</p>
<p>I wrote about related multi-environment configuration issues in this earlier post: <a href="http://www.udidahan.com/2009/08/15/convention-over-configuration-the-next-generation/">Convention over Configuration &#8211; The Next Generation</a></p>
<p>I&#8217;m happy to say that this functionality is now in NServiceBus called &#8220;profiles&#8221; and you can read more about how they work <a href="http://www.nservicebus.com/Profiles.aspx">here</a>.</p>
<p>How are you handling the flow of moving software through to production? Leave your comments below.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2010/06/05/server-naming-and-configuration-conflicts/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>CQRS isn&#8217;t the answer &#8211; it&#8217;s just one of the questions</title>
		<link>http://www.udidahan.com/2010/05/07/cqrs-isnt-the-answer-its-just-one-of-the-questions/</link>
		<comments>http://www.udidahan.com/2010/05/07/cqrs-isnt-the-answer-its-just-one-of-the-questions/#comments</comments>
		<pubDate>Fri, 07 May 2010 09:25:12 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[CQRS]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Simplicity]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1278</guid>
		<description><![CDATA[With the growing interest in Command/Query Responsibility Segregation (CQRS), more people are starting to ask questions about how to apply it to their applications. CQRS is actually in danger of reaching &#8220;best practice&#8221; status at which point in time people will apply it indiscriminately with truly terrible results. 
One of the things that I&#8217;ve been [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/dont_pan.gif" alt="dont panic" title="dont panic" width="260" height="180" style="float:right;" />With the growing interest in Command/Query Responsibility Segregation (<a href="http://www.udidahan.com/2009/12/09/clarified-cqrs/">CQRS</a>), more people are starting to ask questions about how to apply it to their applications. CQRS is actually in danger of reaching &#8220;best practice&#8221; status at which point in time people will apply it indiscriminately with truly terrible results. </p>
<p>One of the things that I&#8217;ve been trying to do with my presentations around the world on CQRS was to explain the <b>why</b> behind it, just as much as the what. The problem with the format of these presentations is that they&#8217;re designed to communicate a fairly closed message: here&#8217;s the problem, here&#8217;s how that problem manifests itself, here&#8217;s a solution.</p>
<p>In this post, I&#8217;m going to try to go deeper.</p>
<h3>The hitchhiker&#8217;s guide to the galaxy</h3>
<p>In this most excellent book, one of the things that struck me was the theme that made it&#8217;s way through the whole book &#8211; starting with the answer to life, the universe, and everything: 42. By the time you get to the end of the book, you find out that the real <b>question</b> to life, the universe, and everything is &#8220;what do you get when you multiply 6 by 9&#8243;. And that&#8217;s how the book leaves it.</p>
<p>To us engineers, we can&#8217;t just accept the fact that the book would say that 6*9 = 42 when we know it&#8217;s 54. After bashing our heads on the rigid rules of math, we realize that not all math problems are necessarily in base 10, and that if we switch to base 13, the number 42 is 4*13 + 2 = 54. So, the book was right &#8211; but that&#8217;s not the point.</p>
<h3>What&#8217;s the point?</h3>
<p>The hitchhiker&#8217;s guide is an example of a teaching technique which presents an apparent paradox, leaving the student to dig up unspoken and unthought assumptions in order to resolve it. Key to this technique are rigid rules which do not allow any compromise or shortcuts on the student&#8217;s part. </p>
<p>The purpose of this technique is not for the student to learn the answer, but to gain deeper understanding, which in turn changes the way they go about thinking about problems in the future. </p>
<p>So, when given the problem 4*5, we do not just immediately answer 20, instead we clarify in which numeric base the question is being phrased, and only then go to solve the problem. In base 13, the answer would be 17. In hex, the answer would be 14.</p>
<p>The externally visible change is that we know which questions to ask in order to arrive at the right answer &#8211; not that we know the answer ahead of time.</p>
<h3>Making an &#8220;ass&#8221; out of &#8220;u&#8221; and &#8220;me&#8221;</h3>
<p>Let&#8217;s start at the end &#8211; one of the unspoken assumptions that has been causing problems:</p>
<blockquote><p>
All businesses can be treated the same from the perspective of software.
</p></blockquote>
<p>In our previous example, we assumed that all math problems use base 10. It turns out that different bases are useful for different domains (like base 2 for computers). We can say similar things about degrees and radians in geometry. The more we look at the real world, the more we see this repeating itself. There&#8217;s no reason that software should be any different.</p>
<p>Base 10 is not a ubiquitous best practice. We shouldn&#8217;t be surprised that there really aren&#8217;t best practices for software either.</p>
<p>Here&#8217;s another problematic assumption:</p>
<blockquote><p>
&#8220;The business&#8221; can (and do) tell us what they need in a way we can understand.
</p></blockquote>
<p>So many software fads have been built on the quicksand of this assumption. OOAD &#8211; on verbs and nouns. 4GL and other visual tools that &#8220;the business&#8221; will use directly. SOA &#8211; on IT business alignment. I expect we haven&#8217;t seen the end of this.</p>
<p>Some of you may be wondering why this is false, others are sagely nodding their heads in agreement.</p>
<h3>The myth of &#8220;the business&#8221;</h3>
<p>Unless you have a single user, who is also the CEO paying for the development, there is no &#8220;the&#8221;. It&#8217;s an amalgam of people with different backgrounds, skills, and goals &#8211; there is no homogeneity. Even if no software was involved, many business organizations are dysfunctional with conflicting goals, policies, and politics.</p>
<p>To some extent, we technical people have hidden ourselves away in IT to avoid the scary world of business whose rules we don&#8217;t understand. With the rise in importance of information to the world, we&#8217;ve been pulled back &#8211; being forced to talk to people, and not just computers. Luckily, we&#8217;ve been able to create a buffer to insulate ourselves &#8211; we&#8217;ve taken the less successful technical people from our heard and nominated them &#8220;business analysts&#8221;. No, not all companies do it this way, but we do need to take a minute to reflect on how information flows between the business Mars into and out of the IT Venus.</p>
<h3>On human communication</h3>
<p>Even if we made this insulation layer more permeable, allowing and encouraging more technical people and business people to cross its boundary, we still need to deal with the problem of two humans communicating with each other. There are enough books that have been written on this topic, so I won&#8217;t go into that beyond recommending (strongly) to technical people to read (some of) them.</p>
<p>Rather, I&#8217;d like to focus on the environment in which these discussions take place. IT has been around long enough, and users have used computers long enough, that a certain amount of tainting has taken place. If the world was a trial, the evidence would have been thrown out as untrustworthy.</p>
<p>When users tell you what they want, they&#8217;re usually framing that with respect to the current system that they&#8217;re using. &#8220;Like the old system &#8211; but faster, and with better search, and more information on that screen, and&#8230;&#8221; </p>
<p>At this point, business analysts write down and formalize these &#8220;requirements&#8221; into some IT-sanctioned structure (use cases, user stories, whatever), at which point developers are told to build it. Users only know what they <b>didn&#8217;t</b> want when developers deliver exactly what was asked.</p>
<p>How can that be?</p>
<h3>These are not the &#8220;requirements&#8221; you are looking for</h3>
<p>Users ultimately dictate <b>solutions</b> to us, as a delta from the previous set of solutions we&#8217;ve delivered them. That&#8217;s just human psychology &#8211; writer&#8217;s block when looking at a blank page, as compared to the ease with which we provide &#8220;constructive criticism&#8221; on somebody else&#8217;s work.</p>
<p>We need to get the real requirements. We need to probe beyond the veneer:</p>
<ul>
<li>Why do you need this additional screen? </li>
<li>What real-world trigger will cause you to open it? </li>
<li>Is there more than one trigger? </li>
<li>How are they different?</li>
<li>etc, etc, etc&#8230;</li>
</ul>
<p>This is <b>real</b> work &#8211; different work than programming. It requires different skills. And that&#8217;s not even getting into the political navigation between competing organizational forces.</p>
<p>But let&#8217;s say that you don&#8217;t have (enough) people with these skills in your organization. What then?</p>
<h3>Enter CQRS</h3>
<p>CQRS gives us a set of questions to ask, and some rigid rules that our answers must conform to. If our answers don&#8217;t fit, we need to go back to the drawing board and move things around and/or go back to &#8220;the business&#8221; and seek deeper understanding there.</p>
<p>For each screen/task/piece of data:</p>
<blockquote><p>
Will multiple users be collaborating on data related to this task?<br />
Look at every shred of raw data, not just at the entity level.<br />
Are there business consistency requirements around groups of raw data?
</p></blockquote>
<p>If &#8220;the business&#8221; answers no &#8211; ask them if they see that answer changing, and if so, in what time frame, and why. What changing conditions in the business environment would cause that to change &#8211; what other parts of the system would need to be re-examined under those conditions.</p>
<p>After understanding all that and you find a true single-user-only-thing, then you can use standard &#8220;CRUD&#8221; techniques and technologies. There are no inherent time-propagation problems in a single-user environment &#8211; so eventual consistency is beyond pointless, it actually makes matters worse.</p>
<p>On the other hand, if the business-data-space is collaborative, the inherent time-propagation of information between actors means they will be making decisions on data that isn&#8217;t up-to-the-millisecond-accurate anyway. This is physics, gravity &#8211; you can&#8217;t fight it (and win).</p>
<h3>The rule for collaboration</h3>
<blockquote><p>
Actors must be able submit one-way commands that will fail only under exceptional <b>business</b> circumstances.
</p></blockquote>
<p>The challenge we have is how to achieve the real business objectives uncovered in our previous &#8220;requirements excavation&#8221; activities and follow this rule at the same time. This will likely involve a different user-system interaction than those implemented in the past. UI design is part of the solution domain &#8211; it shouldn&#8217;t be dictated by the business (otherwise it&#8217;s like someone asking you to run a marathon, but also dictating how you do so, like by tying your shoelaces together).</p>
<p>Many of the technical patterns I described in my <a href="http://www.udidahan.com/2009/12/09/clarified-cqrs/">previous blog post</a> describe the tools involved. BTW, hackers can be considered &#8220;exceptional actors&#8221; &#8211; the business actually wants their commands to fail.</p>
<h3>In Summary</h3>
<p>The hard and fast rule of CQRS about one-way commands is relevant for collaborative domains only. This domain has inherent eventual consistency &#8211; in the real world. Taking that and baking it into our solution domain is how we align with the business.</p>
<p>The process we go through, until ultimately arriving at one-way-almost-always-successful-commands <b>is business analysis</b>. Rejecting pre-formulated solutions, truly understanding the business drivers, and then representing those as directly as possible in our solution domain &#8211; that&#8217;s our job.</p>
<p>After doing this enough times and/or in more than one business domain, we may gain the insight that there is no cookie-cutter, one-size-fits-all, best-practice solution architecture for everything. Each problem domain is distinct and different &#8211; and we need to understand the details, because they <b>should</b> shape the resulting software structure.</p>
<p>The next time the business tell us to implement 42, we&#8217;ll use CQRS along with other questioning techniques until we can get &#8220;6 x 9&#8243; out of them, learning from the exercise what are the significant and stable parts of the business &#8211; ultimately helping us to &#8220;build the right system, and to build the system right&#8221;.</p>
<p>Don&#8217;t Panic <img src='http://www.udidahan.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2010/05/07/cqrs-isnt-the-answer-its-just-one-of-the-questions/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>On MS, OSS, and Java</title>
		<link>http://www.udidahan.com/2010/05/01/on-ms-oss-and-java/</link>
		<comments>http://www.udidahan.com/2010/05/01/on-ms-oss-and-java/#comments</comments>
		<pubDate>Sat, 01 May 2010 11:14:10 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Management]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1272</guid>
		<description><![CDATA[It appears that my last post caught a lot of people&#8217;s attention, with responses online and offline from people in the community as well as inside Microsoft. Some read it as a criticism of Microsoft. Others found it rang true with their experiences, particularly in their interactions with technological decision makers. One thing I&#8217;d like [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/java-logo-thumb.png" alt="Java" title="Java" width="150" height="150" style="float:right;" />It appears that my last post caught a lot of people&#8217;s attention, with responses online and offline from people in the community as well as inside Microsoft. Some read it as a criticism of Microsoft. Others found it rang true with their experiences, particularly in their interactions with technological decision makers. One thing I&#8217;d like to do in this post is to broaden the scope of the discussion to include the Java side as well, as many in the enterprise space are working in a multi-platform/multi-vendor environment. Let&#8217;s start with some history.</p>
<h3>Java takes the enterprise</h3>
<p>When Java originally came out, it was an interesting language that you could use to write applets &#8211; code that would run the same everywhere, in the browser, on the desktop, etc. SUN was the keeper of Java. And then came this concept of a container &#8211; the thing that would run your Java code, which then grew to handle things like transactions, and became the Enterprise Java Bean &#8211; EJB, and that came out of IBM, with SUN adopting it later.</p>
<p>The adoption of Java at that point was important enough that the specs were opened up, and many EJB technologies blossomed. With backing from big companies already inside the enterprise, the only possible fight came from COBOL around Y2K, but that was a dying gasp. Microsoft wasn&#8217;t in the game as Windows NT wasn&#8217;t competition for UNIX or mainframes.</p>
<h3>Multi-vendor as a way of life</h3>
<p>With multiple big and medium-sized vendors offering similar, competing, and complementary technologies, all tied together by the promise of backwards compatibility in Java and the specs demanding interoperability, customers could safely go for best-of-breed solutions. This forced technological decision makers to truly evaluate the offerings on merits, not just lineage.</p>
<p>Many attribute the rise of OSS in Java to the fact that the existing containers were so heavyweight. I believe that was a secondary effect. As a result of the fact that the industry had embraced and internalized the values of thinking and choosing for itself, it was willing to look at alternatives with much humbler lineage, ultimately using them on their merits. It was the culture.</p>
<h3>The Microsoft ecosystem</h3>
<p>This culture was practically nonexistent on the Microsoft side of the border. As the only vendor, Microsoft was put on a pedestal &#8211; it was the best, period. The industry hungrily looked to Seattle not only for technology, but also for guidance and leadership. If a developer could get a job at Microsoft, they were &#8220;hot stuff&#8221;, the best of the best. This isn&#8217;t a bad thing &#8211; it was just a thing.</p>
<p>This enabled technological decision makers on the Microsoft side to have much shorter thought and decision processes than their counterparts on the Java side.</p>
<p>All of these things got baked into the culture.</p>
<h3>About Microsoft</h3>
<p>Like all that were ever on a pedestal, the fall was a matter of time. Expectations being that high, it was inevitable. You can&#8217;t make all people happy all the time, and the conditions in the industry were changing, and the company had to change to remain competitive.</p>
<p>Let me say this clearly: Microsoft was not at fault.</p>
<p>Sure, it&#8217;s easy to say in retrospect they should have communicated more clearly about this, or built that technology differently. If you haven&#8217;t yet worked in a big company, you may not know this, but big companies aren&#8217;t just bigger small companies. It&#8217;s a hodge-podge of competing agenda, initiatives, politics, people, and power. There&#8217;s a saying that things only get done <b>despite</b> the organization&#8217;s best efforts.</p>
<p>For a company Microsoft&#8217;s size, what they manage to get done is incredible.</p>
<h3>On acquisitions and OSS</h3>
<p>Microsoft has come under fire over the years for offering their own implementations of open source technologies- as if the vendors on the Java side didn&#8217;t do this. The Java world was ultra competitive, the big vendors would eat promising upstarts in order to win back lost contracts to key customers. This made the technological decision makers broaden their thought processes to include risk management as a part of managing their technological portfolio. To a large extent, this actually justifies the existence of a C-level role related to technology &#8211; the CIO.</p>
<h3>Chief Officers of Information and Technology</h3>
<p>I found it interesting to see the difference in age, experience, background, and thought processes between people holding the CIO title at organizations that were Microsoft-centric and those with a more heterogeneous technology investment. This was likely influenced to a large extent by the history of technological evolution, age and size of organizations with the resulting culture and hiring practices, among other things. This pattern continued with the CTO as well.</p>
<p>Obviously one wouldn&#8217;t expect the same thought processes in the CTO of a 20 person IT shop and the CTO of Ford Motor Company (for example). They shouldn&#8217;t be the same.</p>
<p>It appeared that as Microsoft became more focused on innovation they started listening more to the technology leaders of smaller companies, not a bad thing by itself. Choosing A means not choosing B, and in order to stay competitive, a choice must be made.</p>
<h3>Fast forward</h3>
<p>I think that what happened was necessary, and will be good for the industry and Microsoft. Technological decision making in companies that were traditionally Microsoft-centric has evolved. This has clarified Microsoft&#8217;s role as a platform vendor who can be trusted, and whose tools can be used or not used as the situation dictates, with comparable commercial and OSS tooling evaluated on the same criteria.</p>
<p>Just as IBM reinvented itself and now occupies a sustainable role in a combined commercial and OSS ecosystem of platforms, tools, and services, Microsoft appears to have made several big strides partnering with the community in much more productive ways, yet with more strides to be made as well.</p>
<h3>A challenge to OSS on the Microsoft platform</h3>
<p>In this new and more mature environment, OSS can&#8217;t remain the same either. Some code a developer whipped up in their free time and put in an online accessible repository with a decent license just won&#8217;t cut it any more.</p>
<p>In my previous post I called out the Linq2Sql support story &#8211; the same goes for OSS. Active development is required, and so is support, and so is documentation. The commitment needs to be much more serious. </p>
<p>Also, until usage reaches some critical mass, it is unlikely that a single developer or even a small group of committers will be able to do it without the help of the community. Really the only alternative is for there to be some commercial story that can fund it &#8211; support, consulting, training, commercial add-ons, etc. A combination of community (both dev and use) and commercial cash-flow is probably most sustainable.</p>
<p>If you are running an OSS project, understand that these criteria will be used to evaluate it.</p>
<h3>In closing</h3>
<p>I think I&#8217;ve managed to alienate previous supporters from all sides.</p>
<p>I believe we are entering some interesting times, where not only are vendors and OSS projects being evaluated differently than in the past, but that traditional architectural paradigms are changing as well. </p>
<p>Regardless of what the answers are, I&#8217;m happy that more of us are asking more questions. Some questions are the right questions, some are the wrong ones, and sometimes we just ask at the wrong time, but as an industry I think that we&#8217;re getting better.</p>
<p>Thanks for reading.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2010/05/01/on-ms-oss-and-java/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Thoughts on Microsoft History and OSS</title>
		<link>http://www.udidahan.com/2010/04/23/thoughts-on-microsoft-history-and-oss/</link>
		<comments>http://www.udidahan.com/2010/04/23/thoughts-on-microsoft-history-and-oss/#comments</comments>
		<pubDate>Fri, 23 Apr 2010 21:47:22 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Integrated Simplicity]]></category>
		<category><![CDATA[Management]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1253</guid>
		<description><![CDATA[It&#8217;s coming on 4 years now that I&#8217;ve been running NServiceBus. How the time flies. As it has worked its way into the critical infrastructure of many organizations, more and more managers have been asking me questions about how this .NET OSS thing works. In this post, I&#8217;ll try to answer that question based on [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/open_source_microsoft.png" alt="open source" title="open source" width="250" height="216" style="float:right;" />It&#8217;s coming on 4 years now that I&#8217;ve been running NServiceBus. How the time flies. As it has worked its way into the critical infrastructure of many organizations, more and more managers have been asking me questions about how this .NET OSS thing works. In this post, I&#8217;ll try to answer that question based on the history of .NET.</p>
<p>Although I have been privy over the years to see behind the veil at Redmond, I will be focusing primarily on the externally visible actions of Microsoft and how the industry has reacted on average &#8211; specifically in the enterprise space, where I spend most of my time. </p>
<h3>What managers are concerned about</h3>
<p>When there will be problem with this technology, who will support us?<br />
How will that change when the author of the technology moves on or loses interest?<br />
How long can we expect to be using this technology?<br />
How long will it take to learn it? When will we recoup our investment?</p>
<p>Traditionally, for companies on the Microsoft platform, choosing Microsoft as their primary technology vendor has been the safe bet. As a large company, Microsoft can afford to employ support engineers. These engineers are different from the ones who wrote the technology to begin with. Also, Microsoft has 10 year support guarantees. As a result, companies expected to use the technology for at least that long. With their size, Microsoft also had the ability to create copious amounts of documentation easing learning.</p>
<p>To turn the common phrase, nobody got fired for choosing Microsoft.</p>
<p>Open source seemed like risky business, at the time.</p>
<h3>What changed?</h3>
<p>It started with the Composite Application Block &#8211; CAB.</p>
<p>This technology was put out by the Patterns and Practices (P&#038;P) group at Microsoft. After it came out, the gears of big marketing machines at Microsoft got to work, telling the industry about this great new thing at conferences, and the Microsoft Consulting Services (MCS) folks started using it with clients. CIOs at large companies sent developers to training on CAB by the dozen.</p>
<p>And then CAB was dead. Sorry. Microsoft prefers the word &#8220;done&#8221; to dead.<br />
Just like Don Box said that COM wasn&#8217;t dead, it was done. </p>
<p>&#8220;What about that 10 year support thing?&#8221;, asked the CIOs (among many others).</p>
<p>You don&#8217;t understand, said Microsoft. You see, P&#038;P are not a product group in Microsoft. They don&#8217;t have the resources to provide that kind of support. And the rest of the company isn&#8217;t obliged to support what they put out &#8211; since they&#8217;re not a product group.</p>
<p>You could literally hear the collective jaw of the Microsoft part of the industry drop.</p>
<p>This wasn&#8217;t supposed to happen (like housing prices in the US).</p>
<p>And then came .NET 3.0, and things seemed to go back to normal.</p>
<p>There were lots of wonderful things that came with it &#8211; like LINQ, and&#8230;</p>
<h3>Linq to Sql</h3>
<p>This was BIG.<br />
Finally &#8211; after ObjectSpaces was promised at PDC &#8216;03 and later shelved, then WinFS (same story), it had arrived.<br />
The object-relational mapper (ORM) from Microsoft.</p>
<p>The marketing machine went into high gear &#8211; it was the v3 promise. Linq2Sql (L2S) came from a product group. This was serious. It was shown at conferences and user groups all over the world. Developers were sent to be trained on it.</p>
<p>And then Entity Framework (EF) was announced &#8211; and L2S was done.</p>
<p>CIOs were rubbing their eyes in disbelief. &#8220;But this is from a product group &#8211; you have to support it, right?&#8221;</p>
<p>Well, said Microsoft, yes. We will support it with our support org. It&#8217;s just that we won&#8217;t continue to develop new features for it in the product org. We actually have a different sub-org that will be working on EF and they&#8217;re under a different division (SQL Server) than the sub-org that made L2S.</p>
<p>Jaws were hitting the pavement. All that investment erased. Just like that. It turns out that support without active development doesn&#8217;t mean very much, no matter how many support engineers are involved.</p>
<p>But the industry picked itself back up, and got back to work on the new foundational pieces that came with .NET 3.0. If Microsoft is calling it &#8220;Foundation&#8221;, that must mean they&#8217;re committed to it.</p>
<h3>And then came Workflow Foundation</h3>
<p>Workflow Foundation (WF) was a dream-come-true. At last, Model-Driven Development (MDD) had come to the Microsoft platform. Drag-and-drop on a whole new level. Imagine the reuse. Imagine the maintainability. Programming at higher levels of abstraction. A marketers dream. This was the culmination of previous efforts of Whitehorse in VS2005 and the Software Factories Initiative &#8211; or so we were told.</p>
<p>And then came .NET 3.5 &#8211; and the new WF wasn&#8217;t backwards compatible with the old one.<br />
And then it happened again with .NET 3.5 SP1, and again with 4.0 (no more state machine &#8211; no wait, it&#8217;s back again, but not in the box).</p>
<p>All those companies that had long-running workflows in production needed to manually migrate them each time.</p>
<p>But this had become old news to the folks using Microsoft in the enterprise.<br />
With Microsoft &#8211; you really can&#8217;t be sure any more.</p>
<h3>What about open source?</h3>
<p>Well, it was beginning to look more and more stable in comparison.<br />
Especially the larger, more established projects. Those with active development.<br />
Log4Net. NHibernate. Castle. etc.</p>
<p>There was also the fact that most enterprises were heterogeneous anyway &#8211; doing both Java and .NET development. Open source tools and frameworks were common in the Java space, politically greasing the wheels for .NET OSS in those organization.</p>
<p>Boasting features and capabilities several years ahead of what was coming out of Microsoft, more companies gave them a chance, and were pleasantly surprised. And the virtuous cycle of OSS gained speed. With more use, they become even more stable and got even more features, driving yet more use. Blog posts about them bloomed all over the web. User group presentations were given. At a presentation I gave at TechEd Europe 2006, I used NHibernate in my demo.</p>
<p>OSS had crossed the chasm. No, not everybody used it, or knew of it, but a critical mass of the industry had grown to depend on it.</p>
<p>Microsoft&#8217;s actions over the years had done more for OSS adoption than I think many would have imagined.</p>
<h3>On Pub/Sub, Messaging, and SOA</h3>
<p>Interestingly enough, when the first version of WCF was still in the oven (then called Indigo) there were discussions on whether it would support publish/subscribe messaging. Here we are, 3 versions later, and still no pub/sub, but the discussions continue <img src='http://www.udidahan.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Message brokers were always important for enterprises in the Java space &#8211; IBM MQ; Tibco RV; Sonic; companies were paying millions for this stuff. Microsoft had MSMQ &#8211; finally at v3 with XP and Server 2003, but still with insignificant penetration to the market. BizTalk did have a good run, though, but not so much as a message broker, more as an integration and orchestration engine, unfortunately coming late to the Enterprise Application Integration (EAI) party.</p>
<p>Later, the SQL Server guys came with Service Broker &#8211; messaging in the database. But you could see that their heart wasn&#8217;t in it. The API was clunky. It still didn&#8217;t have pub/sub. There was no binding available for WCF. </p>
<p>After some time making noise in the SOA space with Oslo, that changed as well. Oslo is now Sql Server Modeling.</p>
<p>I imagine that some of the adoption pick-up with NServiceBus can be attributed to the vacuum Microsoft left behind when exiting the messaging/pub-sub/soa space. The way NServiceBus aligns with the principles found in the corresponding Java technologies makes it very palatable to enterprises working with both platforms.</p>
<p>The fact that there&#8217;s active development, a vibrant and growing community, and even <a href="http://www.udidahan.com/training">training</a> available definitely contribute as well.</p>
<h3>In closing</h3>
<p>I don&#8217;t fault Microsoft for any of this. There are a million things that they could have done. Choosing to do one thing means choosing not to do many others. The decisions they made were done with the best intentions. Hindsight is 20/20 of-course.</p>
<p>And that&#8217;s just it &#8211; we do need to take a look back.</p>
<p>If you&#8217;re a manager making a technology related decision, or are working with managers in those positions, knowing the history of today&#8217;s technology can give you a more accurate representation of the risk involved in each choice. Also, understanding the vector that Microsoft has decided to take in various areas is critical, especially if you find out that your architectural choices aren&#8217;t quite aligned with some of those vectors.</p>
<p>In this post, I&#8217;ve tried not to take a stance on whether a certain approach (ORM, Pub/Sub, etc) is good or bad, or even getting into which cases it&#8217;s appropriate or not &#8211; just to describe Microsoft&#8217;s externally visible behavior in that space.</p>
<p>I hope that this short history lesson can help your organization make the right technology decisions in the future for its specific context. Your comments and thoughts are most welcome, as always.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2010/04/23/thoughts-on-microsoft-history-and-oss/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>On Design for Testability</title>
		<link>http://www.udidahan.com/2010/04/18/on-design-for-testability/</link>
		<comments>http://www.udidahan.com/2010/04/18/on-design-for-testability/#comments</comments>
		<pubDate>Sun, 18 Apr 2010 15:43:57 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[The Team]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1221</guid>
		<description><![CDATA[Almost at every conference, event, training, or consulting engagement someone asks for my opinion on the whole design for testability thing. I&#8217;m not quite sure why I haven&#8217;t blogged on this topic, especially at the time that a lot of the other bloggers were weighing in, but better late than never.
Before getting into that, I [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/elephant_balance.png" style="float:right; margin-left:10px; margin-bottom:10px; " alt="keeping balance" title="keeping balance" width="204" height="203" />Almost at every conference, event, training, or consulting engagement someone asks for my opinion on the whole design for testability thing. I&#8217;m not quite sure why I haven&#8217;t blogged on this topic, especially at the time that a lot of the other bloggers were weighing in, but better late than never.</p>
<p>Before getting into that, I want to start with a slightly broader scope of discussion.</p>
<p>You see, I get asked about &#8220;best practices&#8221; on all sorts of things. And I try not to be the kind of consultant that responds with &#8220;it depends&#8221;, but the context of the question often makes the answer irrelevant. And the unspoken context of a best-practice question is:</p>
<h2>Given infinite time and budget</h2>
<p>The biggest problem that I see with well-intentioned, best-practices-following developers and architects is that they <b>don&#8217;t</b> ask the question &#8220;is this the right thing for us to be focusing on right now?&#8221; Understandably, that is a difficult question to answer &#8211; but it needs to be asked, since you don&#8217;t have infinite time or budget to do everything according to best practices (assuming those even exist).</p>
<h2>About testing</h2>
<p>The biggest issue I have with the &#8220;design for testability&#8221; topic is the extremely narrow view it takes of the word &#8220;testability&#8221;, usually in the form of more code written by a developer which invokes the production code of the system, also known as &#8220;unit tests&#8221;.</p>
<p>There are many different kinds of testing &#8211; unit, integration, functional, load, performance, exploratory, etc&#8230; where some may be automated and others not. Should we not discuss what &#8220;design for testability&#8221; means for not-just-unit-testing?</p>
<h2>And what&#8217;s the point of testing anyway?</h2>
<p>It&#8217;s not to find bugs.</p>
<p>Research has shown that testing (of all kinds) is not the most effective way of finding bugs. I don&#8217;t have the reference handy but I&#8217;m pretty sure that it&#8217;s from <a href="http://alistair.cockburn.us/">Alistair Cockburn&#8217;s work</a>. Code reviews are (on average) about 60% more effective.</p>
<p>Don&#8217;t get me wrong &#8211; testing can provide indications that the software <b>has</b> bugs in it, but not necessarily where in the code those bugs are.</p>
<p>The purpose of testing is to provide quantitative and qualitative information about the system that can help various stakeholders in their decision-making processes. The relevance of that information indicates the quality of the testing. Here are some examples:</p>
<ul>
<li>The system supports 100 concurrent users, with the expected user-type distribution (X% role A, Y% role B, etc), performing expected use-case distributions, and collaboration scenarios.</li>
<li>Time to proficiency for new users in role A is expected to be 3 days</li>
<li>Alternate #2 of use case #12 fails on step #3</li>
</ul>
<p>As you can see, the relevance of the above information is dependent on what decisions the various stakeholders need to make. The bullet on load can help us decide if more machines are needed or if developers need to tune the performance of the systems. The bullet on time to proficiency can help us decide if larger investment in usability is required. Information like the last bullet can be used in conjunction with the first two to decide on the timing and type of a release.</p>
<p>The timeliness of this relevant information is critical to the success of a project.</p>
<p>Choosing which and how much of the various testing activities to perform when is something that needs to be revisited several times throughout the lifetime of a project, taking into account the current risks (threats and probabilities) and time and resource investment to mitigate them.</p>
<p>Let me reiterate &#8211; we&#8217;re not going to have enough time to do everything.</p>
<h2>On iterations</h2>
<p>If the only part of your organization that is doing iterations are your developers, you&#8217;re not agile.</p>
<p>In order to capitalize on the information that testers are providing, you need them in your iterations.</p>
<p>The same goes for the other roles involved in the project &#8211; business analysts, DBAs, sysadmins, etc.</p>
<p>I know that 99% of organizations aren&#8217;t structured in a way to do this.</p>
<p>I never said doing this would be easy.</p>
<h2>On design</h2>
<p>Figuring out what kind of design and how much to do when is just as important, and just as hard. Design for testability is one part of that, but not the only one, or necessarily the most important one at any point of time.</p>
<p>Within that design for testability topic is the &#8220;design for unit-testing&#8221; sub-topic which seems to be the popular one. Before getting into the design aspects of it, let&#8217;s take a closer look at the unit-testing side of things.</p>
<h2>On unit-testing</h2>
<p>The assumption is that having more unit tests will lead to a code-base with less bugs, thus requiring shorter time to get the system into production, which will pay back the time it took to write those unit tests to begin with.</p>
<p>In practice, what tends to happen is that as development progresses, testing code breaks as the structure of the production code changes. Now one of two things happens &#8211; either the testing code is removed or rewritten. In either case, we didn&#8217;t get the return on investment we expected on the first bit of testing code. Unfortunately, rare is the case where the relevant people in the organization understand <b>why</b>, resulting in the same situation repeating itself over and over again.</p>
<p>Those projects would have been better off without unit testing, though the organization as a whole might have used those experiences to learn and improve. It&#8217;s been my experience that if the organization wasn&#8217;t conscious enough in the context of the project to notice the situation, it is unlikely to do so at higher levels.</p>
<h2>On fragile unit tests</h2>
<p>The reason that a unit test ends up being rewritten (or removed) is that its code was coupled to the production code in such a way that it broke when the production code changed. This tendency to break (fragility) is a critical property of a unit test. A fragile unit test will slow down a developer doing work on some existing code &#8211; it actually makes the system less maintainable.</p>
<p>For a unit test code to be stable (not fragile) it needs to be coupled to stable properties of the production code. The question of whether the production code is designed in such a way that it has stable properties &#8211; is a design question. Is it a <b>unit</b>? If not, you will <b>not</b> be able to write a unit-test against it.</p>
<p>And anyway, who said that every class is a unit, or should be a unit? Domain models (when done right) are good examples of a unit, yet the classes that make them up may not be units. Unit-testing should only be attempted with things which are units. </p>
<p>I think too much weight is put on whether a dependency of a class is a concrete or interface type, and not nearly enough on the nature of the dependency. I wouldn&#8217;t blame the hammer for pounding my thumb, and by the same token I think that blame should not be directed towards tools like those from TypeMock.</p>
<h2>On tools</h2>
<p>There is so much more depth to both design and testability that needs to be more broadly understood. No tool has yet been created to handle either design or testing in such a way that humans can give up responsibility for the outcome. </p>
<p>Over the years I&#8217;ve noticed that tools are most significant when used by skilled practitioners, which makes sense in retrospect. Giving a novice carpenter a laser-guided saw probably won&#8217;t significantly change the outcome of their work. Ultimately, the skilled practitioners are the ones that create tools &#8211; not the novices. And no tool, no matter how advanced, will make a novice perform at levels like the skilled practitioner.</p>
<p>In the case of a project too big for a single skilled practitioner to complete in the time required (or at all), the balance of importance shifts away from tools to the project management topics described above.</p>
<h2>In summary</h2>
<p>I hope that this post has shed some light on the context in which decisions with respect to testing need to be made. Design is one activity that can support certain kinds of testing, but not the only one, or even the most important one for the given type of testing necessary at that time in the project.</p>
<p>Design is hard. Project management is hard. Testing is hard.</p>
<p>Getting the right mix of people that together have enough experience and skills in these activities isn&#8217;t easy.</p>
<p>Don&#8217;t expect that sprinkling some interfaces in your code base will be enough.<br />
That doesn&#8217;t count much in the way of design, just as writing code in a testing namespace doesn&#8217;t count much in the way of testability.</p>
<p>Looking forward to hearing your comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2010/04/18/on-design-for-testability/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>On Small Applications</title>
		<link>http://www.udidahan.com/2010/03/07/on-small-applications/</link>
		<comments>http://www.udidahan.com/2010/03/07/on-small-applications/#comments</comments>
		<pubDate>Sun, 07 Mar 2010 11:32:34 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[The Team]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1199</guid>
		<description><![CDATA[I hear this too often: &#8220;X sounds like a great pattern, but it&#8217;s overkill for small applications&#8221;. Many patterns have been subjected to this including (but not limited to): SOA, DDD, CQRS, ORM, etc. Often the statement is made by a person without experience in the given pattern (though possibly experienced in other patterns). Let&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/small_baby.png" style="float:right; margin-left:10px; margin-bottom:10px;" alt="small" title="small" />I hear this too often: &#8220;X sounds like a great pattern, but it&#8217;s overkill for small applications&#8221;. Many patterns have been subjected to this including (but not limited to): SOA, DDD, CQRS, ORM, etc. Often the statement is made by a person without experience in the given pattern (though possibly experienced in other patterns). Let&#8217;s take a look at the second part &#8211; the &#8220;small application&#8221;, and ask:</p>
<h3>What makes an app small?</h3>
<p>Or inversely, what makes an app warrant the &#8220;enterprise&#8221; moniker?</p>
<p>If there&#8217;s one thing that the history of our industry has shown repeatedly, it&#8217;s that developers aren&#8217;t particularly accurate with their estimates. Like, orders-of-magnitude inaccurate. Knowing this, it&#8217;s surprising that the &#8220;small app&#8221; argument seems to win so many arguments. The same goes for justifications in the form of &#8220;we&#8217;ve got to have an X, this is a BIG project&#8221;.</p>
<p>So, what makes an app small? </p>
<p>Is it a small number of lines of code? Well, what if those lines of code are keeping planes in the air?</p>
<p>Is it a small number of developers? Same as above. Actually, history has shown that some of the most valuable bits of code written were done by small numbers of developers. </p>
<p>Is it that it will only be installed on a single machine? </p>
<p>Is it&#8230;</p>
<p>What could it be?</p>
<h3>The real issue</h3>
<p>The small app argument is a diversionary tactic. </p>
<p>Loosely translated, it means &#8220;I&#8217;m comfortable where I am and I don&#8217;t want to change&#8221;.</p>
<p>Moving on&#8230;</p>
<h3>The real story of size</h3>
<p>Once we actually look at the specific context of an app, we tend to see that someone cares a great deal about it, enough to finance its custom development &#8211; rather than buying an off-the-shelf alternative. The expected lifetime of business use is easily 3-5 years, if not 7-10, during which many enhancements will likely be requested. Thus, some non-functional properties of the code matter &#8211; at the very least maintainability.</p>
<p>In which case, if the given pattern or approach does significantly improve the desired non-functional properties of the app, it only makes sense to use it.</p>
<p>There is one class of software that might possibly be treated as &#8220;small&#8221; &#8211; the one-off script that&#8217;s written to automate some IT task. And even then, so many of these scripts end up living longer than the apps themselves that they should be engineered at the same level of quality.</p>
<h3>In closing</h3>
<p>Don&#8217;t counter a &#8220;small app&#8221; argument with psychology.<br />
It will only make matters worse.</p>
<p>Instead, rephrase the issue around the lifetime of business use. </p>
<p>I&#8217;ve found that there are precious few cases where the harsh light of reality doesn&#8217;t help the appropriate decisions be made. If indeed this is a small-lifetime-app, just drag-and-drop until you&#8217;re done. Otherwise, the time it takes to understand and evaluate the applicability of the given patterns will definitely pay itself back many times over the life of the app.</p>
<p>And managers, keep your ears open for it. The technical risks behind that statement are icebergs waiting to sink your project.</p>
<p>* with thanks to <a href="http://devlicious.com/blogs/mike_nichols/archive/2010/03/06/the-biggest-driver-for-domain-modeling-decisions.aspx">Mike Nichols</a> for pushing my buttons.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2010/03/07/on-small-applications/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t Delete &#8211; Just Don&#8217;t</title>
		<link>http://www.udidahan.com/2009/09/01/dont-delete-just-dont/</link>
		<comments>http://www.udidahan.com/2009/09/01/dont-delete-just-dont/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 12:04:48 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Business Rules]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[Data Access]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Validation]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1097</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/no_delete.png" style="float:right; margin-left:10px; margin-bottom:10px; alt="no deletes" title="no deletes" /><br />
After reading Ayende&#8217;s <a href="http://ayende.com/Blog/archive/2009/08/30/avoid-soft-deletes.aspx">post</a> advocating against &#8220;soft deletes&#8221; I felt that I should add a bit more to the topic as there were some important business semantics missing. As developers discuss the pertinence of using an IsDeleted column in the database to mark deletion, and the way this relates to reporting and auditing concerns is weighed, the core domain concepts rarely get a mention. Let&#8217;s first understand the business scenarios we&#8217;re modeling, the why behind them, before delving into the how of implementation.</p>
<h3>The real world doesn&#8217;t cascade</h3>
<p>Let&#8217;s say our marketing department decides to delete an item from the catalog. Should all previous orders containing that item just disappear? And cascading farther, should all invoices for those orders be deleted as well? Going on, would we have to redo the company&#8217;s profit and loss statements?</p>
<p>Heaven forbid.</p>
<p>So, is Ayende wrong? Do we really need soft deletes after all?</p>
<p>On the one hand, we don&#8217;t want to leave our database in an inconsistent state with invoices pointing to non-existent orders, but on the other hand, our users did ask us to delete an entity.</p>
<p>Or did they?</p>
<h3>When all you have is a hammer&#8230;</h3>
<p>We&#8217;ve been exposing users to entity-based interfaces with &#8220;create, read, update, delete&#8221; semantics in them for so long that they have started presenting us requirements using that same language, even though it&#8217;s an extremely poor fit.</p>
<p>Instead of accepting &#8220;delete&#8221; as a normal user action, let&#8217;s go into why users &#8220;delete&#8221; stuff, and what they actually intend to do.</p>
<p>The guys in marketing can&#8217;t actually make all physical instances of a product disappear &#8211; nor would they want to. In talking with these users, we might discover that their intent is quite different:</p>
<blockquote><p>“What I mean by &#8216;delete&#8217; is that the product should be discontinued. We don&#8217;t want to sell this line of product anymore. We want to get rid of the inventory we have, but not order any more from our supplier. The product shouldn&#8217;t appear any more when customers do a product search or category listing, but the guys in the warehouse will still need to manage these items in the interim. It&#8217;s much shorter to just say &#8216;delete&#8217; though.”</p></blockquote>
<p>There seem to be quite a few interesting business rules and processes there, but nothing that looks like it could be solved by a single database column.</p>
<h3>Model the task, not the data</h3>
<p>Looking back at the story our friend from marketing told us, his intent is to discontinue the product &#8211; not to delete it in any technical sense of the word. As such, we probably should provide a more explicit representation of this task in the user interface than just selecting a row in some grid and clicking the &#8216;delete&#8217; button (and &#8220;Are you sure?&#8221; isn&#8217;t it).</p>
<p>As we broaden our perspective to more parts of the system, we see this same pattern repeating:</p>
<blockquote><p>
Orders aren&#8217;t deleted &#8211; they&#8217;re cancelled. There may also be fees incurred if the order is canceled too late.</p>
<p>Employees aren&#8217;t deleted &#8211; they&#8217;re fired (or possibly retired). A compensation package often needs to be handled.</p>
<p>Jobs aren&#8217;t deleted &#8211; they&#8217;re filled (or their requisition is revoked).
</p></blockquote>
<p>In all cases, the thing we should focus on is the task the user wishes to perform, rather than on the technical action to be performed on one entity or another. In almost all cases, more than one entity needs to be considered.</p>
<h3>Statuses</h3>
<p>In all the examples above, what we see is a replacement of the technical action &#8216;delete&#8217; with a relevant business action. At the entity level, instead of having a (hidden) technical WasDeleted status, we see an explicit business status that users need to be aware of.</p>
<p>The manager of the warehouse needs to know that a product is discontinued so that they don&#8217;t order any more stock from the supplier. In today&#8217;s world of retail with Vendor Managed Inventory, this often happens together with a modification to an agreement with the vendor, or possibly a cancellation of that agreement. </p>
<p>This isn&#8217;t just a case of transactional or reporting boundaries &#8211; users in different contexts need to see different things at different times as the status changes to reflect the entity&#8217;s place in the business lifecycle. Customers shouldn&#8217;t see discontinued products at all. Warehouse workers should, that is, until the corresponding Stock Keeping Unit (SKU) has been revoked (another status) after we&#8217;ve sold all the inventory we wanted (and maybe returned the rest back to the supplier).</p>
<h3>Rules and Validation</h3>
<p>When looking at the world through over-simplified-delete-glasses, we may consider the logic dictating when we can delete to be quite simple: do some role-based-security checks, check that the entity exists, delete. Piece of cake.</p>
<p>The real world is a bigger, more complicated cake.</p>
<p>Let&#8217;s consider deleting an order, or rather, canceling it. On top of the regular security checks, we&#8217;ve got some rules to consider:</p>
<blockquote><p>
If the order has already been delivered, check if the customer isn&#8217;t happy with what they got, and go about <b>returning</b> the order. </p>
<p>If the order contained products &#8220;made to order&#8221;, charge the customer for a portion (or all) of the order (based on other rules).</p>
<p>And more&#8230;
</p></blockquote>
<p>Deciding what the next status should be may very well depend on the current business status of the entity. Deciding if that change of state is allowed is context and time specific &#8211; at one point in time the task may have been allowed, but later not. The logic here is not necessarily entirely related to the entity being &#8220;deleted&#8221; &#8211; there may be other entities which need to be checked, and whose status may also need  to be changed as well.</p>
<h3>Summary</h3>
<p>I know that some of you are thinking, &#8220;my system isn&#8217;t that complex &#8211; we can just delete and be done with it&#8221;.</p>
<p>My question to you would be, have you asked your users <b>why</b> they&#8217;re deleting things? Have you asked them about additional statuses and rules dictating how entities move as groups between them? You don&#8217;t want the success of your project to be undermined by that kind of unfounded assumption, do you?</p>
<p>The reason we&#8217;re given budgets to build business applications is because of the richness in business rules and statuses that ultimately provide value to users and a competitive advantage to the business. If that value wasn&#8217;t there, wouldn&#8217;t we be serving our users better by just giving them Microsoft Access?</p>
<p>In closing, given that you&#8217;re not giving your users MS Access, don&#8217;t think about deleting entities. Look for the reason why. Understand the different statuses that entities move between. Ask which users need to care about which status. I know it doesn&#8217;t show up as nicely on your resume as &#8220;3 years WXF&#8221;, but &#8220;saved the company $4 million in wasted inventory&#8221; does speak volumes.</p>
<p>One last sentence: Don&#8217;t delete. Just don&#8217;t.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2009/09/01/dont-delete-just-dont/feed/</wfw:commentRss>
		<slash:comments>56</slash:comments>
		</item>
		<item>
		<title>Convention over Configuration &#8211; The Next Generation?</title>
		<link>http://www.udidahan.com/2009/08/15/convention-over-configuration-the-next-generation/</link>
		<comments>http://www.udidahan.com/2009/08/15/convention-over-configuration-the-next-generation/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 18:13:24 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[NServiceBus]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1081</guid>
		<description><![CDATA[
Convention over configuration describes a style of development made popular by Ruby on Rails which has gained a great deal of traction in the .net ecosystem. After using frameworks designed in this way, I can say that the popularity is justified &#8211; it is much more pleasurable developing this way. 
The thing is, when looking [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/PicardKirk.jpg" alt="PicardKirk" title="PicardKirk" width="160" height="103" style="float:right; margin-left:10px; margin-bottom:10px; " /><br />
Convention over configuration describes a style of development made popular by Ruby on Rails which has gained a great deal of traction in the .net ecosystem. After using frameworks designed in this way, I can say that the popularity is justified &#8211; it is much more pleasurable developing this way. </p>
<p>The thing is, when looking at this in light of the full software development lifecycle, there are signs that the waters run deeper than we might have originally thought.</p>
<p>Let&#8217;s take things one step at a time though&#8230;</p>
<h3>What is it?</h3>
<p><a href="http://en.wikipedia.org/wiki/Convention_over_configuration">Wikipedia tells us</a>:</p>
<blockquote><p>&#8220;Convention over Configuration (aka Coding by convention) is a software design paradigm which seeks to decrease the number of decisions that developers need to make, gaining simplicity, but not necessarily losing flexibility. The phrase essentially means a developer only needs to specify unconventional aspects of the application.&#8221;</p></blockquote>
<p>What this means is that frameworks built in this way have default implementations that can be swapped out if needed. So far so good.</p>
<h3>For example&#8230;</h3>
<p>In <a href="http://www.NServiceBus.com">NServiceBus</a>, there is an abstraction for how subscription data is stored and multiple implementations &#8211; one in-memory, another using a durable MSMQ queue, and a third which uses a database. The convention for that part of the system is that the MSMQ implementation will be used, unless something else is specified. </p>
<p>Developers wishing to specify a different implementation can specify the desired implementation in the container &#8211; either one that comes out of the box, or their own implementation of ISubscriptionStorage.</p>
<p>Things get more interesting when we consider the full lifecycle.</p>
<h3>Lifecycle effects</h3>
<p>When developers are in the early phases of writing a new service, they want to focus primarily on what the service does &#8211; its logic. They don&#8217;t want to muck around with MSMQ queues for storing subscriptions and would much rather use the in-memory storage. </p>
<p>As the service takes shape and the developers want to run the full service on their machine, possibly testing basic fault-tolerance behaviors &#8211; kill one service, see that the others get a timeout, bring the service back up, wanting it to maintain all the previous subscriptions.</p>
<p>Moving on from there, our developers want to take the same system they just tested on their machine and move it into a staging environment. There, they don&#8217;t want to use the MSMQ implementation for subscription storage, but rather the database implementation &#8211; as will be used in the production environment. </p>
<p>While it may not sound like a big deal &#8211; changing the code which specifies which implementation to use when moving from one environment to another, consider that on top of just subscription storage, there is logging (output to console, file, db?), saga persistence (in-memory, file-based DB, relational DB), and more.</p>
<p>It&#8217;s actually quite likely that something will get missed as we move the system between environments. Can there be a better way?</p>
<h3>What if&#8230;</h3>
<p>What if there was some way for the developer to express their intent to the system, and the system could change its conventions, without the developer having to change any code or configuration files?</p>
<p>You might compare this (in concept) to debug builds and release builds. Same code, same config, but the runtime behaves different between the two.</p>
<p>As I mulled over how we could capture that intent without any code or config changes, the solution that I kept coming to seemed too trivial at first, so I dismissed it. Yet, it was the simplest one that would work for console and WinForms applications, as well as windows services &#8211; command line arguments. The only thing is that I don&#8217;t think those are available for web applications.</p>
<p>But since we&#8217;re still in &#8220;what if&#8221; land, and I&#8217;m more thinking out loud here than providing workable solutions for tomorrow morning, let&#8217;s &#8220;what if&#8221; command line arguments worked for web apps too.</p>
<h3>Command-Line Intent</h3>
<p>Going back to our original scenario, when developers are working on the logic of the service, they run it using the generic NServiceBus host process, passing it the command line parameter /lite (or whatever). The host then automatically configures all the in-memory implementations. </p>
<p>As the system progresses, when the developer wants to run everything on their machine, they run the processes with /integration. The host then configures the appropriate implementations (MSMQ for subscription storage, SQLite for saga persistence, etc. </p>
<p>When the developers want to run the system in production, they could specify /production (or maybe that could be the default?), and the database backed implementations would be configured.</p>
<h3>Imagine&#8230;</h3>
<p>Imagine being able to move that fluidly from one environment to another. Not needing to pore over configuration files or startup script code which configures a zillion implementation details. Not needing to worry that as you moved the system to staging something would break.</p>
<p>Imagine short, frictionless iterations even for large scale systems.</p>
<p>Imagine &#8211; lifecycle-aware frameworks making all this imagination a reality.</p>
<h3>In Closing</h3>
<p>We&#8217;re not there yet &#8211; but we&#8217;re not that far either. The generic host we&#8217;re providing with NServiceBus 2.0 is now being extended to support exactly these scenarios. </p>
<p>It&#8217;s my hope that as more of us think about this challenge, we&#8217;ll come up with better solutions and more intelligent frameworks. Just as convention came to our rescue before, breaking us out of the pain of endless XML configuration, I hope this new family of lifecycle-aware frameworks will make the friction of moving a system through dev, test, staging, and production a thing of the past.</p>
<p>A worthy problem for us all to solve, don&#8217;t you think?</p>
<p>Any ideas on how to make it a reality?<br />
Send them in &#8211; leave a comment below.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2009/08/15/convention-over-configuration-the-next-generation/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>Domain Events &#8211; Salvation</title>
		<link>http://www.udidahan.com/2009/06/14/domain-events-salvation/</link>
		<comments>http://www.udidahan.com/2009/06/14/domain-events-salvation/#comments</comments>
		<pubDate>Sun, 14 Jun 2009 06:25:31 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[Data Access]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1029</guid>
		<description><![CDATA[
I&#8217;ve been hearing from people that have had a great deal 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 change is that now we&#8217;ll be taking [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/sphere1.jpg" alt="sphere" title="sphere" width="198" height="201"  style="border-right: 0px; border-top: 0px; margin: 0px 10px; border-left: 0px; border-bottom: 0px" align="right"/><br />
I&#8217;ve been hearing from people that have had a great deal of success using the Domain Event pattern and the infrastructure I previously provided for it in <a href="http://www.udidahan.com/2008/08/25/domain-events-take-2/">Domain Events &#8211; Take 2</a>. I&#8217;m happy to say that I&#8217;ve got an improvement that I think you&#8217;ll like. The main change is that now we&#8217;ll be taking an approach that is reminiscent to how events are published in <a href="http://www.NServiceBus.com">NServiceBus</a>.</p>
<h3>Background</h3>
<p>Before diving right into the code, I wanted to take a minute to recall how we got here.</p>
<p>It started by looking for <a href="http://www.udidahan.com/2008/02/29/how-to-create-fully-encapsulated-domain-models/">how to create fully encapsulated domain models</a>.</p>
<p>The main assertion being that you do *not* need to inject anything into your domain entities.</p>
<p>Not services. Not repositories. Nothing.</p>
<p>Just pure domain model goodness.</p>
<h3>Make Roles Explicit</h3>
<p>I&#8217;m going to take the advice I so often give. A domain event is a role, and thus should be represented explicitly:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">public</span> <span class="kwrd">interface</span> IDomainEvent {}</pre>
</div>
<p>If this reminds you of the IMessage marker interface in nServiceBus, you&#8217;re beginning to see where this is going&#8230;</p>
<h3>How to define domain events</h3>
<p>A domain event is just a simple POCO that represents an interesting occurence in the domain. For example:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">public</span> <span class="kwrd">class</span> CustomerBecamePreferred : IDomainEvent </pre>
<pre><span class="lnum">   2:  </span>{</pre>
<pre class="alt"><span class="lnum">   3:  </span>    <span class="kwrd">public</span> Customer Customer { get; set; }</pre>
<pre><span class="lnum">   4:  </span>}</pre>
</div>
<p>For those of you concerned about the number of events you may have, and therefore are thinking about bunching up these events by namespaces or things like that, slow down. The number of domain events and their cohesion is directly related to that of the domain model. </p>
<p>If you feel the need to split your domain events up, there&#8217;s a good chance that you should be looking at splitting your domain model too. This is the bottom-up way of identifying bounded contexts.</p>
<h3>How to raise domain events</h3>
<p>In your domain entities, when a significant state change happens you&#8217;ll want to raise your domain events like this:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">public</span> <span class="kwrd">class</span> Customer</pre>
<pre><span class="lnum">   2:  </span>{</pre>
<pre class="alt"><span class="lnum">   3:  </span>    <span class="kwrd">public</span> <span class="kwrd">void</span> DoSomething()</pre>
<pre><span class="lnum">   4:  </span>    {</pre>
<pre class="alt"><span class="lnum">   5:  </span>        DomainEvents.Raise(<span class="kwrd">new</span> CustomerBecamePreferred() { Customer = <span class="kwrd">this</span> });</pre>
<pre><span class="lnum">   6:  </span>    }</pre>
<pre class="alt"><span class="lnum">   7:  </span>}</pre>
</div>
<p>We&#8217;ll look at the DomainEvents class in just a second, but I&#8217;m guessing that some of you are wondering &#8220;how did that entity get a reference to that?&#8221; The answer is that DomainEvents is a static class. &#8220;OMG, static?! But doesn&#8217;t that hurt testability?!&#8221; No, it doesn&#8217;t. Here, look:</p>
<h3>Unit testing with domain events</h3>
<p>One of the things we&#8217;d like to check when unit testing our domain entities is that the appropriate events are raised along with the corresponding state changes. Here&#8217;s an example:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">public</span> <span class="kwrd">void</span> DoSomethingShouldMakeCustomerPreferred()</pre>
<pre><span class="lnum">   2:  </span>{</pre>
<pre class="alt"><span class="lnum">   3:  </span>    var c = <span class="kwrd">new</span> Customer();</pre>
<pre><span class="lnum">   4:  </span>    Customer preferred = <span class="kwrd">null</span>;</pre>
<pre class="alt"><span class="lnum">   5:  </span>&nbsp;</pre>
<pre><span class="lnum">   6:  </span>    DomainEvents.Register&lt;CustomerBecamePreferred&gt;(</pre>
<pre class="alt"><span class="lnum">   7:  </span>        p =&gt; preferred = p.Customer</pre>
<pre><span class="lnum">   8:  </span>            );</pre>
<pre class="alt"><span class="lnum">   9:  </span>&nbsp;</pre>
<pre><span class="lnum">  10:  </span>    c.DoSomething();</pre>
<pre class="alt"><span class="lnum">  11:  </span>    Assert(preferred == c &amp;&amp; c.IsPreferred);</pre>
<pre><span class="lnum">  12:  </span>}</pre>
</div>
<p>As you can see, the static DomainEvents class is used in unit tests as well. Also notice that you don&#8217;t need to mock anything &#8211; pure testable bliss.</p>
<h3>Who handles domain events</h3>
<p>First of all, consider that when some service layer object calls the DoSomething method of the Customer class, it doesn&#8217;t necessarily know which, if any, domain events will be raised. All it wants to do is its regular schtick:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">public</span> <span class="kwrd">void</span> Handle(DoSomethingMessage msg)</pre>
<pre><span class="lnum">   2:  </span>{</pre>
<pre class="alt"><span class="lnum">   3:  </span>    <span class="kwrd">using</span> (ISession session = SessionFactory.OpenSession())</pre>
<pre><span class="lnum">   4:  </span>    <span class="kwrd">using</span> (ITransaction tx = session.BeginTransaction())</pre>
<pre class="alt"><span class="lnum">   5:  </span>    {</pre>
<pre><span class="lnum">   6:  </span>        var c = session.Get&lt;Customer&gt;(msg.CustomerId);</pre>
<pre class="alt"><span class="lnum">   7:  </span>        c.DoSomething();</pre>
<pre><span class="lnum">   8:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">   9:  </span>        tx.Commit();</pre>
<pre><span class="lnum">  10:  </span>    }</pre>
<pre class="alt"><span class="lnum">  11:  </span>}</pre>
</div>
<p>The above code complies with the Single Responsibility Principle, so the business requirement which states that when a customer becomes preferred, they should be sent an email belongs somewhere else. </p>
<p>Notice that the key word in the requirement &#8211; &#8220;when&#8221;.</p>
<p>Any time you see that word in relation to your domain, consider modeling it as a domain event.</p>
<p>So, here&#8217;s the handling code:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">public</span> <span class="kwrd">class</span> CustomerBecamePreferredHandler : Handles&lt;CustomerBecamePreferred&gt;</pre>
<pre><span class="lnum">   2:  </span>{ </pre>
<pre class="alt"><span class="lnum">   3:  </span>   <span class="kwrd">public</span> <span class="kwrd">void</span> Handle(CustomerBecamePreferred args)</pre>
<pre><span class="lnum">   4:  </span>   {</pre>
<pre class="alt"><span class="lnum">   5:  </span>      <span class="rem">// send email to args.Customer</span></pre>
<pre><span class="lnum">   6:  </span>   }</pre>
<pre class="alt"><span class="lnum">   7:  </span>} </pre>
</div>
<p>This code will run no matter which service layer object we came in through.</p>
<p>Here&#8217;s the interface it implements:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">public</span> <span class="kwrd">interface</span> Handles&lt;T&gt; <span class="kwrd">where</span> T : IDomainEvent</pre>
<pre><span class="lnum">   2:  </span>{</pre>
<pre class="alt"><span class="lnum">   3:  </span>    <span class="kwrd">void</span> Handle(T args); </pre>
<pre><span class="lnum">   4:  </span>} </pre>
</div>
<p>Fairly simple.</p>
<p>Please be aware that the above code will be run on the same thread within the same transaction as the regular domain work so you should avoid performing any blocking activities, like using SMTP or web services. Instead, prefer using one-way messaging to communicate to something else which does those blocking activities.</p>
<p>Also, you can have multiple classes handling the same domain event. If you need to send email *and* call the CRM system *and* do something else, etc, you don&#8217;t need to change any code &#8211; just write a new handler. This keeps your system quite a bit more stable than if you had to mess with the original handler or, heaven forbid, service layer code.</p>
<h3>Where domain event handlers go</h3>
<p>These handler classes do not belong in the domain model.</p>
<p>Nor do they belong in the service layer.</p>
<p>Well, that&#8217;s not entirely accurate &#8211; you see, there&#8217;s no *the* service layer. There is the part that accepts messages from clients and calls methods on the domain model. And there is another, independent part that handles events from the domain. Both of these will probably make use of a message bus, but that implementation detail shouldn&#8217;t deter you from keeping each in their own package.</p>
<h3>The infrastructure</h3>
<p>I know you&#8217;ve been patient, reading through all my architectural blah-blah, so here it is:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">class</span> DomainEvents</pre>
<pre><span class="lnum">   2:  </span>{ </pre>
<pre class="alt"><span class="lnum">   3:  </span>    [ThreadStatic] <span class="rem">//so that each thread has its own callbacks</span></pre>
<pre><span class="lnum">   4:  </span>    <span class="kwrd">private</span> <span class="kwrd">static</span> List&lt;Delegate&gt; actions;</pre>
<pre class="alt"><span class="lnum">   5:  </span>&nbsp;</pre>
<pre><span class="lnum">   6:  </span>    <span class="kwrd">public</span> <span class="kwrd">static</span> IContainer Container { get; set; } <span class="rem">//as before</span></pre>
<pre class="alt"><span class="lnum">   7:  </span>&nbsp;</pre>
<pre><span class="lnum">   8:  </span>    <span class="rem">//Registers a callback for the given domain event</span></pre>
<pre class="alt"><span class="lnum">   9:  </span>    <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> Register&lt;T&gt;(Action&lt;T&gt; callback) <span class="kwrd">where</span> T : IDomainEvent</pre>
<pre><span class="lnum">  10:  </span>    {</pre>
<pre class="alt"><span class="lnum">  11:  </span>       <span class="kwrd">if</span> (actions == <span class="kwrd">null</span>)</pre>
<pre><span class="lnum">  12:  </span>          actions = <span class="kwrd">new</span> List&lt;Delegate&gt;();</pre>
<pre class="alt"><span class="lnum">  13:  </span>&nbsp;</pre>
<pre><span class="lnum">  14:  </span>       actions.Add(callback);</pre>
<pre class="alt"><span class="lnum">  15:  </span>   }</pre>
<pre><span class="lnum">  16:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  17:  </span>   <span class="rem">//Clears callbacks passed to Register on the current thread</span></pre>
<pre><span class="lnum">  18:  </span>   <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> ClearCallbacks ()</pre>
<pre class="alt"><span class="lnum">  19:  </span>   {</pre>
<pre><span class="lnum">  20:  </span>       actions = <span class="kwrd">null</span>;</pre>
<pre class="alt"><span class="lnum">  21:  </span>   }</pre>
<pre><span class="lnum">  22:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  23:  </span>   <span class="rem">//Raises the given domain event</span></pre>
<pre><span class="lnum">  24:  </span>   <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> Raise&lt;T&gt;(T args) <span class="kwrd">where</span> T : IDomainEvent</pre>
<pre class="alt"><span class="lnum">  25:  </span>   {</pre>
<pre><span class="lnum">  26:  </span>      <span class="kwrd">if</span> (Container != <span class="kwrd">null</span>)</pre>
<pre class="alt"><span class="lnum">  27:  </span>         <span class="kwrd">foreach</span>(var handler <span class="kwrd">in</span> Container.ResolveAll&lt;Handles&lt;T&gt;&gt;())</pre>
<pre><span class="lnum">  28:  </span>            handler.Handle(args);</pre>
<pre class="alt"><span class="lnum">  29:  </span>&nbsp;</pre>
<pre><span class="lnum">  30:  </span>      <span class="kwrd">if</span> (actions != <span class="kwrd">null</span>)</pre>
<pre class="alt"><span class="lnum">  31:  </span>          <span class="kwrd">foreach</span> (var action <span class="kwrd">in</span> actions)</pre>
<pre><span class="lnum">  32:  </span>              <span class="kwrd">if</span> (action <span class="kwrd">is</span> Action&lt;T&gt;)</pre>
<pre class="alt"><span class="lnum">  33:  </span>                  ((Action&lt;T&gt;)action)(args);</pre>
<pre><span class="lnum">  34:  </span>   }</pre>
<pre class="alt"><span class="lnum">  35:  </span>} </pre>
</div>
<p>Notice that while this class *can* use a container, the container isn&#8217;t needed for unit tests which use the Register method.</p>
<p>When used server side, please make sure that you add a call to ClearCallbacks in your infrastructure&#8217;s end of message processing section. In nServiceBus this is done with a message module like the one below:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">public</span> <span class="kwrd">class</span> DomainEventsCleaner : IMessageModule</pre>
<pre><span class="lnum">   2:  </span>{ </pre>
<pre class="alt"><span class="lnum">   3:  </span>    <span class="kwrd">public</span> <span class="kwrd">void</span> HandleBeginMessage() { }</pre>
<pre><span class="lnum">   4:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">   5:  </span>    <span class="kwrd">public</span> <span class="kwrd">void</span> HandleEndMessage()</pre>
<pre><span class="lnum">   6:  </span>    {</pre>
<pre class="alt"><span class="lnum">   7:  </span>        DomainEvents.ClearCallbacks();</pre>
<pre><span class="lnum">   8:  </span>    }</pre>
<pre class="alt"><span class="lnum">   9:  </span>}</pre>
</div>
<p>The main reason for this cleanup is that someone just might want to use the Register API in their original service layer code rather than writing a separate domain event handler.</p>
<h3>Summary</h3>
<p>Like all good things in life, 3rd time&#8217;s the charm.</p>
<p>It took a couple of iterations, and the API did change quite a bit, but the overarching theme has remained the same &#8211; keep the domain model focused on domain concerns. While some might say that there&#8217;s only a slight technical difference between calling a service (IEmailService) and using an event to dispatch it elsewhere, I beg to differ.</p>
<p>These domain events are a part of the ubiquitous language and should be represented explicitly.</p>
<p>CustomerBecamePreferred is nothing at all like IEmailService.</p>
<p>In working with your domain experts or just going through a requirements document, pay less attention to the nouns and verbs that Object-Oriented Analysis &#038; Design call attention to, and keep an eye out for the word &#8220;when&#8221;. It&#8217;s a critically important word that enables us to model important occurrences and state changes.</p>
<p>What do you think? Are you already using this approach? Have you already tried it and found it broken in some way? Do you have any suggestions on how to improve it?</p>
<p>Let me know &#8211; leave a comment below.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2009/06/14/domain-events-salvation/feed/</wfw:commentRss>
		<slash:comments>127</slash:comments>
		</item>
		<item>
		<title>Projects, Assemblies, and Namespaces &#8211; oh my</title>
		<link>http://www.udidahan.com/2009/05/03/projects-assemblies-and-namespaces-oh-my/</link>
		<comments>http://www.udidahan.com/2009/05/03/projects-assemblies-and-namespaces-oh-my/#comments</comments>
		<pubDate>Sun, 03 May 2009 19:45:34 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Simplicity]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1008</guid>
		<description><![CDATA[Every once in a while this topic pops up, and since the nServiceBus code base doesn&#8217;t follow the apparently accepted practice, and I do get asked about it, here goes.
First of all, the conventional wisdom:
&#8220;If you don&#8217;t choose assembly to represent component, the natural artifact candidate is then namespace.&#8221;
There&#8217;s only one minor assumption here that [...]]]></description>
			<content:encoded><![CDATA[<p>Every once in a while this topic pops up, and since the nServiceBus code base doesn&#8217;t follow the apparently accepted practice, and I do get asked about it, here goes.</p>
<p>First of all, the <a href="http://codebetter.com/blogs/patricksmacchia/archive/2009/05/03/can-we-avoid-tooling-to-prevent-spaghetti-code.aspx">conventional wisdom</a>:</p>
<blockquote><p>&#8220;If you don&#8217;t choose assembly to represent component, the natural artifact candidate is then namespace.&#8221;</p></blockquote>
<p>There&#8217;s only one minor assumption here that deserves being dragged out into the light.</p>
<p>While Visual Studio creates an assembly from every project by default, you <i>can</i> take those assemblies and merge them together into a single assembly using <a href="http://research.microsoft.com/en-us/people/mbarnett/ilmerge.aspx">this nice little utility</a> from Microsoft. It is likely that each project would have its own namespace too, so we should still be aligned with the conventional wisdom.</p>
<p>In other words, we <i>could</i> choose a Visual Studio project to represent a logical component and still be in the same camp as <a href="http://codebetter.com/blogs/jeremy.miller/archive/2008/10/10/183438.aspx">Jeremy</a>:</p>
<blockquote><p>&#8220;I&#8217;m very firmly in the camp that says you should only split assemblies by deployment targets&#8221;</p></blockquote>
<p>What everyone agrees about seems to be that <b>coupling hurts, and should be managed</b>.</p>
<p>Where does coupling come from? Well, from references between two pieces of code. <b>If</b> we were to represent our logical components as Visual Studio projects, we could easily see those references without the help of any 3rd party tools. The compiler would even yell at us if we were to (accidentally) create an evil circular reference.</p>
<p>While some might complain about the long compile time when we have many projects in a single solution, good componentization often doesn&#8217;t require us to put all projects in a single solution. In fact, each component could theoretically have its own solution &#8211; since it&#8217;s reasonable to assume we&#8217;d really only be working on one component at a time. In which case, compile time per developer task would be a non-issue.</p>
<p>Going through the whole code base is usually only needed when doing a full-system debug when trying to track down a problem. This wouldn&#8217;t need to be done against a solution with all projects. We&#8217;d do this using PDBs of the merged projects (as that&#8217;s what actually got delivered, and where the bug was found). After spelunking through those PDBs, we&#8217;d eventually find the problematic component (or 2, or 3, or &#8230;), and open up developer tasks for each component. </p>
<p>Regardless of if we&#8217;re putting out a patch for an existing customer or rolling these changes into a release with other tasks, all the logical components would be built into a physical system (merged as necessary) and the system would be put through QA.</p>
<p>In short, it looks like just a bit of unconventional wisdom gets us a nice balance.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2009/05/03/projects-assemblies-and-namespaces-oh-my/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Unit Testing for Developers and Managers</title>
		<link>http://www.udidahan.com/2008/09/30/unit-testing-for-developers-and-managers/</link>
		<comments>http://www.udidahan.com/2008/09/30/unit-testing-for-developers-and-managers/#comments</comments>
		<pubDate>Tue, 30 Sep 2008 21:03:10 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[The Team]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/2008/09/30/unit-testing-for-developers-and-managers/</guid>
		<description><![CDATA[ &#8220;We need to rewrite the system.&#8221;
Thus begins the story of yet another developer trying to convince their manager to adopt test-driven development (or any other methodology or technology). There&#8217;s a good chance this developer&#8217;s been reading all sorts of stuff on blogs (like those linked here) that have convinced him that salvation lies that [...]]]></description>
			<content:encoded><![CDATA[<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 0px 10px 10px; border-right-width: 0px" height="240" alt="image" src="http://www.udidahan.com/wp-content/uploads/image44.png" width="178" align="right" border="0"> &#8220;We need to rewrite the system.&#8221;</p>
<p>Thus begins the story of yet another developer trying to convince their manager to adopt test-driven development (or any other methodology or technology). There&#8217;s a good chance this developer&#8217;s been reading all sorts of stuff on blogs (like those linked <a href="http://weblogs.asp.net/rosherove/archive/2008/09/26/unit-testing-decoupled-from-design-adoption.aspx">here</a>) that have convinced him that salvation lies that way.</p>
<p>Don&#8217;t get me wrong. </p>
<p>There&#8217;s a good chance the developer&#8217;s right. </p>
<p>It&#8217;s just that that&#8217;s besides the point.</p>
<h3>Developers and Managers</h3>
<p>There&#8217;s a difference between how developers view a practice and how a manager (defined for the purposes of this post as someone in charge of delivering something) view that same practice. From a developer perspective, <a href="http://codebetter.com/blogs/ian_cooper/archive/2008/09/23/learning-and-crafstmanship.aspx">Ian&#8217;s point</a> about unit testing is spot on:</p>
<blockquote><p>&#8220;The problem is that the most important step is not doing it right, but doing it at all.&#8221;</p>
</blockquote>
<p>Yet, as Ian himself points out in the title, this is a learning issue. If you want to learn to swim, there&#8217;s no replacement for jumping in the pool. </p>
<p>The manager&#8217;s perspective is a bit different.</p>
<p>Yes, we want our developers to improve their skill set. Yes, we understand that unit testing will <em>ultimately</em> improve quality. Yes, we know developers need to practice these skills as a part of their job. But, and it&#8217;s a big ole&#8217; but, when it comes time to sink or swim, and we&#8217;ve got a deadline, those desires need to be balanced with delivering. <a href="http://weblogs.asp.net/rosherove/archive/2008/09/20/goodbye-mocks-farewell-stubs.aspx">Accounts</a> of unit testing adoption efforts resulting in more (test) code to support with little apparent improvement in quality in the short term, well, they scare us. <a href="http://www.rgoarchitects.com/nblog/2008/09/21/WhatsUpWithUnitTestingPartI.aspx">Arnon&#8217;s post</a> gives more links supporting that feeling.</p>
<h3>What&#8217;s a Unit Test anyway?</h3>
<p>Is it any class that happens to have a TestFixture attribute on it?</p>
<p>If we are to &#8220;decouple&#8221; unit testing from good design, as <a href="http://weblogs.asp.net/rosherove/archive/2008/09/26/unit-testing-decoupled-from-design-adoption.aspx">Roy has described</a>, that&#8217;s a not-improbable outcome. If the design of the system is such as there aren&#8217;t any real &#8220;units&#8221;, what exactly are we testing? Regardless of static or dynamic typing, replaceability of code, and other technological things, does the fact that all TestMethods in that TestFixture complete successfully mean anything? In other words, what did the test test?</p>
<p>It is clear that these tests <em>cost</em> something.</p>
<p>It&#8217;s more code to write. It&#8217;s more code to maintain.</p>
<p>The question is, what value are we getting from these &#8220;unit tests that any developer without design skills can write&#8221;?</p>
<p>The manager in me doesn&#8217;t like this return on investment.</p>
<blockquote><p>By the way, TDD is as much the evolution of unit testing as the screw driver is the evolution of the hammer. But that&#8217;ll have to wait for a different post.</p>
</blockquote>
<h3>What&#8217;s Design Got To Do With It?</h3>
<p>If you&#8217;re looking for the technical ability to write a test fixture and replace calls to other classes, then design has nothing to it.</p>
<p>If tests are to be valuable &#8211; design has everything to do with it.</p>
<p>The difficulty our developer is having unit-testing the system is a symptom of design problems. There&#8217;s a good chance that&#8217;s why he suggested a rewrite. </p>
<blockquote><p>By the way, please do a search &amp; replace in your vocabulary on the word &#8220;rewrite&#8221; with the word &#8220;redesign&#8221;. The code&#8217;s syntax isn&#8217;t the problem &#8211; it&#8217;s not the &#8220;m_&#8221;, camel case, or anything like that. It&#8217;s not that if the code was rewritten under the same design that all problems will go away.</p>
<p>Redesign, or do nothing.</p>
</blockquote>
<p>The community&#8217;s been discussing the issues of coupling, interfaces, mocking, and tools at length in the context of testability. I won&#8217;t reiterate the debate here but I&#8217;ll tell you this:</p>
<p>If logic is duplicated, if the code is tightly coupled, if there is no separation of concerns, the unit tests will be useless &#8211; even if they &#8220;test&#8221; the class in isolation.</p>
<h3>Cut the coverage crap</h3>
<p>Metrics lie.</p>
<p>The fact that there&#8217;s a bunch of other code which calls 100% of the system&#8217;s code and doesn&#8217;t contain false assertions doesn&#8217;t mean that the code is high quality or doesn&#8217;t contain bugs.</p>
<p>In a well designed system, most &#8220;logic&#8221; will be contained in two &#8220;layers&#8221; &#8211; the controllers and the domain model. These classes should be independent of any and all technological concerns. You can and should get high unit test coverage on classes in these layers. Shoot for 100%, it&#8217;s worth it.</p>
<blockquote><p>Testing domain models is all about asserting state. While using setters to get the domain objects into a necessary initial state is OK, setters should not be used beyond that. Testing controllers is primarily about interactions &#8211; mocks will probably be needed for views and service agents. Commands do not need to be mocked out.</p>
</blockquote>
<p>Most other layers have some dependence on technology that makes unit tests relatively less valuable. Coverage on these layers is most meaningless. My guidance is to take the effort that would have been spent on unit testing these other layers and invest it all in automated integration tests. You&#8217;re likely to get a much higher return on investment. Much higher.</p>
<p>Much.</p>
<h3>Everybody&#8217;s Right</h3>
<p>Developers aren&#8217;t just born knowing good design, testing, or anything else. Universities, colleges, and most vendors do little to change that state of affairs. Books help, a bit, but when learning to swim, you&#8217;ve got to get your feet wet, and on the job training is, by and large, all there is. As such, lowering the barrier to entry is important. </p>
<p>Keeping in mind the <a href="http://w3.msi.vxu.se/~per/CP-web/PBDDSKIL.HTM">Dreyfus model of knowledge acquisition</a>, it&#8217;s not about &#8220;<a href="http://ayende.com/Blog/archive/2008/09/23/cuddling-is-consider-harmful.aspx">dumbing down</a>&#8221; software development, it&#8217;s about bringing novices up to speed:</p>
<blockquote><p>&#8220;In the beginning [novices] learn to recognize objective facts and features, relevant to the skill. Characteristic of relevant elements are that they can be recognized context-free, i.e. without reference to the overall situation. The novice acquire basic rules to follow, acting upon those facts and features. The rules are also context-free, i.e. no notice is taken to the surroundings. <strong>On account of this the novice feels very little responsibility for the result</strong>.&#8221; (emphasis mine)</p>
</blockquote>
<p>Managers <strong><em>are</em></strong> ultimately responsible for the result. </p>
<p>Managers shouldn&#8217;t necessarily sacrifice their projects on this altar of learning. Organizations need to find ways for developers to safely practice these techniques as a part of developing their &#8220;human resources&#8221;. First of all, this needs to be communicated to everyone &#8211; that the organization understands the importance of these techniques, the desires of developers to adopt them, and the projects that need to be delivered. </p>
<p>Some projects may be allocated additional non-functional requirements: the software will be developed test-first, there will be at least 80% unit test coverage, etc. It can make sense to have developers spend some time on these projects after finishing one more delivery focused project and before going onto another one. As more developers become proficient with unit testing and design, the delivery focused projects can start to benefit from these skills.</p>
<p>It&#8217;s a gradual process.</p>
<h2>The Important Bit</h2>
<p>No matter how you go about unit testing, do periodic test reviews.</p>
<p>Just like code reviews.</p>
<p>That&#8217;s it.</p>
<p>&nbsp;</p>
<hr size="1">
<h4>Related Posts</h4>
<blockquote><p><a href="http://www.udidahan.com/2008/02/04/sagas-and-unit-testing-business-process-verification-made-easy/">Business Process Verification</a></p>
<p><a href="http://www.udidahan.com/2007/04/16/self-documenting-test-driven-alien-artifacts/">Self documenting and Test-Driven Alien Artifacts</a></p>
<p><a href="http://www.udidahan.com/2006/06/16/soa-testing/">SOA Testing</a></p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2008/09/30/unit-testing-for-developers-and-managers/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Domain Events &#8211; Take 2</title>
		<link>http://www.udidahan.com/2008/08/25/domain-events-take-2/</link>
		<comments>http://www.udidahan.com/2008/08/25/domain-events-take-2/#comments</comments>
		<pubDate>Mon, 25 Aug 2008 13:40:41 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[Data Access]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Threading]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/2008/08/25/domain-events-take-2/</guid>
		<description><![CDATA[Update: The next post in this series is now online here.
My previous post on how to create fully encapsulated domain models introduced the concept of events as a core pattern of communication from the domain back to the service layer. In that post, I put up enough code to get the idea across but didn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p><b>Update:</b> The next post in this series is now online <a href="http://www.udidahan.com/2009/06/14/domain-events-salvation/">here</a>.</p>
<p>My previous post on <a href="http://www.udidahan.com/2008/02/29/how-to-create-fully-encapsulated-domain-models/">how to create fully encapsulated domain models</a> introduced the concept of events as a core pattern of communication from the domain back to the service layer. In that post, I put up enough code to get the idea across but didn&#8217;t address issues like memory leaks and multi-threading. This post will show the solution to those two critical points.</p>
<p> <center><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="63" alt="" src="http://www.udidahan.com/wp-content/uploads/image43.png" width="500" border="0"></center>
</p>
<p>I&#8217;ve snipped out one of the events in the previous example for brevity.</p>
<h3>Previous API</h3>
<p>The previous API looked like this:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">class</span> DomainEvents</pre>
<pre><span class="lnum">   2:  </span>{</pre>
<pre class="alt"><span class="lnum">   3:  </span>     <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">event</span> EventHandler GameReportedLost;</pre>
<pre><span class="lnum">   4:  </span>     <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> RaiseGameReportedLostEvent()</pre>
<pre class="alt"><span class="lnum">   5:  </span>     {</pre>
<pre><span class="lnum">   6:  </span>           <span class="kwrd">if</span> (GameReportedLost != <span class="kwrd">null</span>)</pre>
<pre class="alt"><span class="lnum">   7:  </span>               GameReportedLost(<span class="kwrd">null</span>, <span class="kwrd">null</span>);</pre>
<pre><span class="lnum">   8:  </span>     }</pre>
<pre class="alt"><span class="lnum">   9:  </span>&nbsp;</pre>
<pre><span class="lnum">  10:  </span>     <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">event</span> EventHandler CartIsFull;</pre>
<pre class="alt"><span class="lnum">  11:  </span>     <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> RaiseCartIsFull()</pre>
<pre><span class="lnum">  12:  </span>     {</pre>
<pre class="alt"><span class="lnum">  13:  </span>           <span class="kwrd">if</span> (CartIsFull != <span class="kwrd">null</span>)</pre>
<pre><span class="lnum">  14:  </span>               CartIsFull(<span class="kwrd">null</span>, <span class="kwrd">null</span>);</pre>
<pre class="alt"><span class="lnum">  15:  </span>     }</pre>
<pre><span class="lnum">  16:  </span>}</pre>
</div>
<p>One thing that we want to keep in the solution is that all the code to define events, their names, and the parameters they bring will be in one place &#8211; in this case, the DomainEvents class. One thing that we&#8217;d like to fix is the amount of code needed to define an event.</p>
<h3>Previous Service Layer</h3>
<p>Here&#8217;s what our previous service layer code looked like:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">public</span> <span class="kwrd">class</span> AddGameToCartMessageHandler :</pre>
<pre><span class="lnum">   2:  </span>    BaseMessageHandler&lt;AddGameToCartMessage&gt;</pre>
<pre class="alt"><span class="lnum">   3:  </span>{</pre>
<pre><span class="lnum">   4:  </span>    <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Handle(AddGameToCartMessage m)</pre>
<pre class="alt"><span class="lnum">   5:  </span>    {</pre>
<pre><span class="lnum">   6:  </span>        <span class="kwrd">using</span> (ISession session = SessionFactory.OpenSession())</pre>
<pre class="alt"><span class="lnum">   7:  </span>        <span class="kwrd">using</span> (ITransaction tx = session.BeginTransaction())</pre>
<pre><span class="lnum">   8:  </span>        {</pre>
<pre class="alt"><span class="lnum">   9:  </span>            ICart cart = session.Get&lt;ICart&gt;(m.CartId);</pre>
<pre><span class="lnum">  10:  </span>            IGame g = session.Get&lt;IGame&gt;(m.GameId);</pre>
<pre class="alt"><span class="lnum">  11:  </span>&nbsp;</pre>
<pre><span class="lnum">  12:  </span>            Domain.DomainEvents.GameReportedLost +=</pre>
<pre class="alt"><span class="lnum">  13:  </span>              gameReportedLost;</pre>
<pre><span class="lnum">  14:  </span>            Domain.DomainEvents.CartIsFull +=</pre>
<pre class="alt"><span class="lnum">  15:  </span>              cartIsFull;</pre>
<pre class="alt"><span class="lnum">  16:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  17:  </span>            cart.Add(g);</pre>
<pre><span class="lnum">  18:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  19:  </span>            Domain.DomainEvents.GameReportedLost -=</pre>
<pre><span class="lnum">  20:  </span>              gameReportedLost;</pre>
<pre class="alt"><span class="lnum">  21:  </span>            Domain.DomainEvents.CartIsFull -=</pre>
<pre><span class="lnum">  22:  </span>              cartIsFull;</pre>
<pre class="alt"><span class="lnum">  23:  </span>&nbsp;</pre>
<pre><span class="lnum">  24:  </span>            tx.Commit();</pre>
<pre class="alt"><span class="lnum">  25:  </span>        }</pre>
<pre><span class="lnum">  26:  </span>    }</pre>
<pre class="alt"><span class="lnum">  27:  </span>&nbsp;</pre>
<pre><span class="lnum">  28:  </span>    <span class="kwrd">private</span> EventHandler gameReportedLost = <span class="kwrd">delegate</span> { </pre>
<pre class="alt"><span class="lnum">  29:  </span>          Bus.Return((<span class="kwrd">int</span>)ErrorCodes.GameReportedLost);</pre>
<pre><span class="lnum">  30:  </span>        };</pre>
<pre class="alt"><span class="lnum">  31:  </span>&nbsp;</pre>
<pre><span class="lnum">  32:  </span>    <span class="kwrd">private</span> EventHandler cartIsFull = <span class="kwrd">delegate</span> { </pre>
<pre class="alt"><span class="lnum">  33:  </span>          Bus.Return((<span class="kwrd">int</span>)ErrorCodes.CartIsFull);</pre>
<pre><span class="lnum">  34:  </span>        };</pre>
<pre class="alt"><span class="lnum">  35:  </span>    }</pre>
<pre><span class="lnum">  36:  </span>}</pre>
</div>
<p>Another thing that should be improved is the amount of code needed in the service layer.</p>
<p>Raising an event, though, should still be fairly simple &#8211; one line of code similar to DomainEvents.RaiseGameReportedLost().</p>
<h3>New API</h3>
<p>Here&#8217;s what the new API looks like:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">class</span> DomainEvents</pre>
<pre><span class="lnum">   2:  </span>{</pre>
<pre class="alt"><span class="lnum">   3:  </span>     <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">readonly</span> DomainEvent&lt;IGame&gt; GameReportedLost = </pre>
<pre><span class="lnum">   4:  </span>                                          <span class="kwrd">new</span> DomainEvent&lt;IGame&gt;;</pre>
<pre class="alt"><span class="lnum">   5:  </span>&nbsp;</pre>
<pre><span class="lnum">   6:  </span>     <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">readonly</span> DomainEvent&lt;ICart&gt; CartIsFull=</pre>
<pre class="alt"><span class="lnum">   7:  </span>                                          <span class="kwrd">new</span> DomainEvent&lt;ICart&gt;;</pre>
<pre><span class="lnum">   8:  </span>}</pre>
</div>
<p>It looks like we&#8217;ve managed to bring down the complexity of defining an event.</p>
<p>Raising an event is slightly different, but still only one line of code (&#8221;this&#8221; refers to the Cart class that is calling this API): DomainEvents.CartIsFull.Raise(<span class="kwrd">this</span>);</p>
<h3>New Service Layer</h3>
<p>The advantage of having a disposable domain event allows us to use the &#8220;using&#8221; construct for cleanup.</p>
<p><p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">public</span> <span class="kwrd">class</span> AddGameToCartMessageHandler :</pre>
<pre><span class="lnum">   2:  </span>    BaseMessageHandler&lt;AddGameToCartMessage&gt;</pre>
<pre class="alt"><span class="lnum">   3:  </span>{</pre>
<pre><span class="lnum">   4:  </span>    <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Handle(AddGameToCartMessage m)</pre>
<pre class="alt"><span class="lnum">   5:  </span>    {</pre>
<pre><span class="lnum">   6:  </span>        <span class="kwrd">using</span> (ISession session = SessionFactory.OpenSession())</pre>
<pre class="alt"><span class="lnum">   7:  </span>        <span class="kwrd">using</span> (ITransaction tx = session.BeginTransaction())</pre>
<pre><span class="lnum">   8:  </span>        <span class="kwrd">using</span> (DomainEvents.GameReportedLost.Register(gameReportedLost))</pre>
<pre class="alt"><span class="lnum">   9:  </span>        <span class="kwrd">using</span> (DomainEvents.CartIsFull.Register(cartIsFull))</pre>
<pre><span class="lnum">  10:   </span>       {</pre>
<pre class="alt"><span class="lnum">  11:  </span>            ICart cart = session.Get&lt;ICart&gt;(m.CartId);</pre>
<pre><span class="lnum">  12:  </span>            IGame g = session.Get&lt;IGame&gt;(m.GameId);</pre>
<pre class="alt"><span class="lnum">  13:  </span>&nbsp;</pre>
<pre><span class="lnum">  14:  </span>            cart.Add(g);</pre>
<pre class="alt"><span class="lnum">  15:  </span>&nbsp;</pre>
<pre><span class="lnum">  16:  </span>            tx.Commit();</pre>
<pre class="alt"><span class="lnum">  17:  </span>        }</pre>
<pre><span class="lnum">  18:  </span>    }</pre>
<pre class="alt"><span class="lnum">  19:  </span>&nbsp;</pre>
<pre><span class="lnum">  20:  </span>    <span class="kwrd">private</span> Action&lt;IGame&gt; gameReportedLost = <span class="kwrd">delegate</span> { </pre>
<pre class="alt"><span class="lnum">  21:  </span>          Bus.Return((<span class="kwrd">int</span>)ErrorCodes.GameReportedLost);</pre>
<pre><span class="lnum">  22:  </span>        };</pre>
<pre class="alt"><span class="lnum">  23:  </span>&nbsp;</pre>
<pre><span class="lnum">  24:  </span>    <span class="kwrd">private</span> Action&lt;ICart&gt; cartIsFull = <span class="kwrd">delegate</span> { </pre>
<pre class="alt"><span class="lnum">  25:  </span>          Bus.Return((<span class="kwrd">int</span>)ErrorCodes.CartIsFull);</pre>
<pre><span class="lnum">  26:  </span>        };</pre>
<pre class="alt"><span class="lnum">  27:  </span>    }</pre>
<pre><span class="lnum">  28:  </span>}</pre>
</div>
<p>I also want to mention that you don&#8217;t necessarily have to have the same service layer object handle these events as that which calls the domain objects. In other words, we can have singleton objects handling these events for things like sending emails, notifying external systems, and auditing.</p>
<h3>The Infrastructure</h3>
<p>The infrastructure that makes all this possible (in a thread-safe way) is quite simple and made up of two parts, the DomainEvent that we saw being used above, and the DomainEventRegistrationRemover which handles the disposing:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">using</span> System;</pre>
<pre><span class="lnum">   2:  </span><span class="kwrd">using</span> System.Collections.Generic;</pre>
<pre class="alt"><span class="lnum">   3:  </span>&nbsp;</pre>
<pre><span class="lnum">   4:  </span><span class="kwrd">namespace</span> DomainEventInfrastructure</pre>
<pre class="alt"><span class="lnum">   5:  </span>{</pre>
<pre><span class="lnum">   6:  </span>    <span class="kwrd">public</span> <span class="kwrd">class</span> DomainEvent&lt;E&gt; </pre>
<pre class="alt"><span class="lnum">   7:  </span>    {</pre>
<pre><span class="lnum">   8:  </span>        [ThreadStatic] </pre>
<pre class="alt"><span class="lnum">   9:  </span>        <span class="kwrd">private</span> <span class="kwrd">static</span> List&lt;Action&lt;E&gt;&gt; _actions; </pre>
<pre><span class="lnum">  10:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  11:  </span>        <span class="kwrd">protected</span> List&lt;Action&lt;E&gt;&gt; actions </pre>
<pre><span class="lnum">  12:  </span>        {</pre>
<pre class="alt"><span class="lnum">  13:  </span>            get { </pre>
<pre><span class="lnum">  14:  </span>                <span class="kwrd">if</span> (_actions == <span class="kwrd">null</span>) </pre>
<pre class="alt"><span class="lnum">  15:  </span>                    _actions = <span class="kwrd">new</span> List&lt;Action&lt;E&gt;&gt;(); </pre>
<pre><span class="lnum">  16:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  17:  </span>                <span class="kwrd">return</span> _actions; </pre>
<pre><span class="lnum">  18:  </span>            }</pre>
<pre class="alt"><span class="lnum">  19:  </span>        }</pre>
<pre><span class="lnum">  20:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  21:  </span>        <span class="kwrd">public</span> IDisposable Register(Action&lt;E&gt; callback) </pre>
<pre><span class="lnum">  22:  </span>        {</pre>
<pre class="alt"><span class="lnum">  23:  </span>            actions.Add(callback);</pre>
<pre><span class="lnum">  24:  </span>            <span class="kwrd">return</span> <span class="kwrd">new</span> DomainEventRegistrationRemover(<span class="kwrd">delegate</span></pre>
<pre class="alt"><span class="lnum">  25:  </span>                {</pre>
<pre><span class="lnum">  26:  </span>                    actions.Remove(callback);</pre>
<pre class="alt"><span class="lnum">  27:  </span>                }</pre>
<pre><span class="lnum">  28:  </span>            ); </pre>
<pre class="alt"><span class="lnum">  29:  </span>        }</pre>
<pre><span class="lnum">  30:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  31:  </span>        <span class="kwrd">public</span> <span class="kwrd">void</span> Raise(E args) </pre>
<pre><span class="lnum">  32:  </span>        {</pre>
<pre class="alt"><span class="lnum">  33:  </span>            <span class="kwrd">foreach</span> (Action&lt;E&gt; action <span class="kwrd">in</span> actions) </pre>
<pre><span class="lnum">  34:  </span>                action.Invoke(args);</pre>
<pre class="alt"><span class="lnum">  35:  </span>        }</pre>
<pre><span class="lnum">  36:  </span>    }</pre>
<pre class="alt"><span class="lnum">  37:  </span>}</pre>
<pre><span class="lnum">  38:  </span>&nbsp;</pre>
</div>
<p>Note that the invocation list of the domain event is thread static, meaning that each thread gets its own copy &#8211; even though they&#8217;re all working with the same instance of the domain event.</p>
<p>Here&#8217;s the DomainEventRegistrationRemover &#8211; even simpler:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">using</span> System;</pre>
<pre><span class="lnum">   2:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">   3:  </span><span class="kwrd">namespace</span> DomainEventInfrastructure</pre>
<pre><span class="lnum">   4:  </span>{</pre>
<pre class="alt"><span class="lnum">   5:  </span>    <span class="kwrd">public</span> <span class="kwrd">class</span> DomainEventRegistrationRemover : IDisposable </pre>
<pre><span class="lnum">   6:  </span>    {</pre>
<pre class="alt"><span class="lnum">   7:  </span>        <span class="kwrd">private</span> <span class="kwrd">readonly</span> Action CallOnDispose;</pre>
<pre><span class="lnum">   8:  </span> </pre>
<pre class="alt"><span class="lnum">   9:  </span>        <span class="kwrd">public</span> DomainEventRegistrationRemover(Action ToCall) </pre>
<pre><span class="lnum">  10:  </span>        {</pre>
<pre class="alt"><span class="lnum">  11:  </span>            <span class="kwrd">this</span>.CallOnDispose = ToCall; </pre>
<pre><span class="lnum">  12:  </span>        }</pre>
<pre class="alt"><span class="lnum">  13:  </span>&nbsp;</pre>
<pre><span class="lnum">  14:  </span>        <span class="kwrd">public</span> <span class="kwrd">void</span> Dispose() </pre>
<pre class="alt"><span class="lnum">  15:  </span>        {</pre>
<pre><span class="lnum">  16:  </span>            <span class="kwrd">this</span>.CallOnDispose.DynamicInvoke();</pre>
<pre class="alt"><span class="lnum">  17:  </span>        }</pre>
<pre><span class="lnum">  18:  </span>    }</pre>
<pre class="alt"><span class="lnum">  19:  </span>}</pre>
</div>
<p>For your convenience, I&#8217;ve made these available for <a href="http://www.udidahan.com/wp-content/uploads/domaineventinfrastructure.zip">download here</a>.</p>
<p>I also want to add that if you haven&#8217;t looked at the comments on the original post &#8211; there&#8217;s some really good stuff there (36 comments so far). <a href="http://www.udidahan.com/2008/02/29/how-to-create-fully-encapsulated-domain-models">Take a look</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2008/08/25/domain-events-take-2/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Logging &#8211; The Smart Way</title>
		<link>http://www.udidahan.com/2008/08/01/logging-the-smart-way/</link>
		<comments>http://www.udidahan.com/2008/08/01/logging-the-smart-way/#comments</comments>
		<pubDate>Fri, 01 Aug 2008 13:07:20 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[AOP]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Logging]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/2008/08/01/logging-the-smart-way/</guid>
		<description><![CDATA[Don&#8217;t.
Not in applicative code anyway.
This follows up on Ayende&#8217;s post about the AOP way.
Now, I have nothing against AOP but some developers are leery of it.
In broader terms, all logging goes in framework-level code. For smart clients, one really good place to put logging is in your Command infrastructure &#8211; every time a command is [...]]]></description>
			<content:encoded><![CDATA[<p>Don&#8217;t.</p>
<p>Not in applicative code anyway.</p>
<p>This follows up on Ayende&#8217;s post about the <a href="http://ayende.com/Blog/archive/2008/07/31/Logging--the-AOP-way.aspx">AOP way</a>.</p>
<p>Now, I have nothing against AOP but some developers are leery of it.</p>
<p>In broader terms, all logging goes in framework-level code. For smart clients, one really good place to put logging is in your Command infrastructure &#8211; every time a command is invoked, log it and the args. For data access, well, any decent O/R Mapper has a lot of logging already, just use it. For communication, ditto. Funny that just last week this was one of the major bits of feedback I gave in a code review.</p>
<h4>The Important Part <a href="http://www.udidahan.com/wp-content/uploads/image34.png"><img style="border-right: 0px; border-top: 0px; margin: 0px 0px 10px 10px; border-left: 0px; border-bottom: 0px" height="204" alt="image" src="http://www.udidahan.com/wp-content/uploads/image-thumb30.png" width="244" align="right" border="0"></a> </h4>
<p>Logging is useful for developers to find out <em>why</em> a system isn&#8217;t working correctly.</p>
<p>It is terrible for knowing <em>that</em> a system isn&#8217;t working correctly.</p>
<p>If you&#8217;re entire exception management strategy is &#8220;write it to the log&#8221;, how will an admin know that something&#8217;s wrong? Did you remember to configure your logging library that errors (and maybe warnings too) should be pushed out to a monitoring system? Do you have a monitoring system?</p>
<p>And if the admins don&#8217;t know anything&#8217;s wrong, they won&#8217;t know they need to increase the fidelity of the logs, will they? Are you planning on providing training for your admins telling them this (and all the other things they need to know)? Or maybe this will all be set up as an automatic script?</p>
<h4>An Agile Digression</h4>
<p>I hope all that&#8217;s on your agile (&#8221;we can ship at the end of every 2 week iteration&#8221;) product backlog (pardon my cynicism). I hope it&#8217;s at least something that you&#8217;re looking at per release and feeding the relevant features into your iterations. Yes, there&#8217;s project work to do (writing training manuals) that isn&#8217;t &#8220;development&#8221; that needs to be handled; if you don&#8217;t timebox it into the same iterations, it won&#8217;t get done.</p>
<p>Now, back to you&#8217;re regularly schedule logging&#8230;</p>
<h4>Things Logging Doesn&#8217;t Address<a href="http://www.udidahan.com/wp-content/uploads/image35.png"><img style="border-right: 0px; border-top: 0px; margin: 0px 0px 10px 10px; border-left: 0px; border-bottom: 0px" height="244" alt="image" src="http://www.udidahan.com/wp-content/uploads/image-thumb31.png" width="140" align="right" border="0"></a> </h4>
<p>Logging is a mildly useless tool for pinpointing <em>where</em> in the system the source of a problem is.</p>
<blockquote><p>&#8220;I know the entity isn&#8217;t in the database. I can see that. I want to know <em>why</em> it isn&#8217;t there.&#8221;</p>
</blockquote>
<p>Sure, if you had every SQL statement logged you could figure these sorts of things out out. Of course, performance-wise, you wouldn&#8217;t put the system into production like that. In which case, the delete statement wouldn&#8217;t have been logged leaving you with precious little information to solve the root cause.</p>
<p>Also consider that the more logging you do, the more crap you&#8217;ll have to sift through to find the proverbial needle. Developers often don&#8217;t think twice about increasing the amount of <strike>crap</strike> logs they generate&#8230;</p>
<h4>The Real Problem</h4>
<p>The real problem is that developers think too much about logging and not <strike>at all</strike> nearly enough about designing the system in ways that it&#8217;ll be <strike>easy</strike> possible to answer questions like those above without having to know exactly how the system is built. One of the reasons that developers should care about this is that it&#8217;ll decrease the number of times they need to get up at 3:00 am to answer those questions.</p>
<h4>A Path to the Solution<a href="http://www.udidahan.com/wp-content/uploads/image36.png"><img style="border-right: 0px; border-top: 0px; margin: 0px 0px 10px 10px; border-left: 0px; border-bottom: 0px" height="244" alt="image" src="http://www.udidahan.com/wp-content/uploads/image-thumb32.png" width="184" align="right" border="0"></a> </h4>
<p>Now, if you had some kind of business activity monitoring (BAM) capability in your system, an admin could do a simple search/query [WHEN entity DELETED] and find out answers to the questions above, find out the time that the relevant activities occurred, figure out what the problem is on their own, and maybe even fix it &#8211; especially if it has to do with some esoteric configuration variable.Regardless of whether you buy a BAM tool or roll what you need yourself, you need to understand what about the system needs to be monitored. That&#8217;s a very different thought-process to go through than &#8220;should we log this? Yeah, sure, why not.&#8221;</p>
<p>It&#8217;s called &#8220;Design for Operations&#8221;.</p>
<p>Take a holistic perspective on exception management, logging, monitoring, etc. Think about questions like those above and then analyse your use of the relevant tools in that context. Think about all the different kinds of users of the information that&#8217;s going to be generated and how quickly their going to need to act on that information. Admins in the data-center in the middle of a crisis are going to have different needs than developers analysing logs on their machine. Think about:</p>
<ul>
<li>How will the administrator know that a server has been configured properly?</li>
<li>If the system is feeling slow, how can the administrator know which server/process is to blame?</li>
<ul>
<li>So that maybe they can scale out that part of the system.</li>
</ul>
</ul>
<h4>In Closing<a href="http://www.udidahan.com/wp-content/uploads/image37.png"><img style="border-right: 0px; border-top: 0px; margin: 0px 0px 10px 10px; border-left: 0px; border-bottom: 0px" height="162" alt="image" src="http://www.udidahan.com/wp-content/uploads/image-thumb33.png" width="162" align="right" border="0"></a> </h4>
<p>It&#8217;s a mindset. </p>
<p>It takes time to make the shift.</p>
<p>It takes more time to bring the development process to this kind of maturity (god, I hate that word).</p>
<p>Writing exceptions to the log is not a strategy.</p>
<p>At the very best, its a tactic.</p>
<p>What&#8217;s your strategy?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2008/08/01/logging-the-smart-way/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>External Value Configuration with IoC</title>
		<link>http://www.udidahan.com/2008/06/13/external-value-configuration-with-ioc/</link>
		<comments>http://www.udidahan.com/2008/06/13/external-value-configuration-with-ioc/#comments</comments>
		<pubDate>Fri, 13 Jun 2008 16:32:11 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Dependency Injection]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Simplicity]]></category>

		<guid isPermaLink="false">http://udidahan.weblogs.us/2008/06/13/external-value-configuration-with-ioc/</guid>
		<description><![CDATA[One of the things I haven&#8217;t like about using IoC containers, AKA dependency injection frameworks, was the string-based configuration model they exposed. In order to set these values, developers had 2 options: either use XML config (usually without the benefit of intellisense or refactoring support), or use code (still quoting property names &#8211; again, no [...]]]></description>
			<content:encoded><![CDATA[<p>One of the things I haven&#8217;t like about using IoC containers, AKA dependency injection frameworks, was the string-based configuration model they exposed. In order to set these values, developers had 2 options: either use XML config (usually without the benefit of intellisense or refactoring support), or use code (still quoting property names &#8211; again, no intellisense or refactoring support).
<p>In short, there seemed to be a hole in the development model.
<p>Here&#8217;s an example from how nServiceBus used to do this:<br />
<blockquote>
<p>builder.ConfigureComponent(typeof(<b><font color="#800000">HttpTransport</font></b>), <b><font color="#800000">ComponentCallModelEnum</font></b>.Singleton)<br />&nbsp; .ConfigureProperty(&#8221;DefaultNumberOfWorkerThreads&#8221;, 10)<br />&nbsp; .ConfigureProperty(&#8221;DefaultNumberOfSenderThreads&#8221;, 10);</p>
</blockquote>
<p>The problem was that if a developer got the case of the property wrong, misspelled it in some way, or somebody later refactored/renamed that property, the system would break. It would also be very difficult to figure out why.
<p>Then, a couple of weeks ago, it dawned on me.
<p>This was the same problem we used to have with testing using mock objects &#8211; before we had today&#8217;s more advanced frameworks. So, the solution must be to use the same techniques. The container should give the developer an object that looks just like their class, but that would intercept all calls. Then, that interceptor could turn those into the config calls shown above. Here&#8217;s what the new config model looks like:&nbsp;<br />
<blockquote>
<p><b><font color="#800000">HttpTransport</font></b> transport = builder.ConfigureComponent&lt;<b><font color="#800000">HttpTransport</font></b>&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (<b><font color="#800000">ComponentCallModelEnum</font></b>.Singleton);</p>
<p>transport.DefaultNumberOfSenderThreads = 10; <br />transport.DefaultNumberOfWorkerThreads = 10;&nbsp; </p>
</blockquote>
<p>Granted, you&#8217;re not going to have tons of code like this. However, for all those parameters which are factory-configured and that customers/integrators shouldn&#8217;t tinker with, it makes a difference. The biggest difference is during that time of development where you&#8217;ve gotten into preliminary integration tests but the systems components are still being &#8220;polished&#8221;.</p>
<blockquote><p><strong>Aside</strong>: On the current project that has adopted this model, we&#8217;ve probably saved (conservatively) about 3 months of effort with this tiny (?) thing, and this isn&#8217;t a huge project. If that&#8217;s more than you would&#8217;ve thought, well, I was surprised myself. First, understand that in the old config model, everything still compiles and unit tests pass, even though its broken.</p>
<p>Just consider what happens in the lab when this occurs. You have N testers that can&#8217;t test the new version, waiting. You have the person who installed the version, trying to figure out what&#8217;s wrong. They then call in one of the developers where most of the new development occurred since the previous version. They fiddle around with it, looking at exception traces and whatnot. In the best case, we&#8217;re talking about 2 hours from noticing its broken until a new version comes out fixed. Multiply that by N+3 people. Then multiply by the number of versions you do integration tests on in the lab.</p>
</blockquote>
<p><strong>Caveat:</strong> In the current version, properties must be virtual in order for this to work.</p>
<p>For those of you who want just this feature without nServiceBus, I&#8217;ve put up all the binaries <a href="http://cid-c8ad44874742a74d.skydrive.live.com/self.aspx/Blog/Builder.zip">here</a>. For the source, you&#8217;ll need to go to <a href="http://nservicebus.svn.sourceforge.net/viewvc/nservicebus/src/impl/ObjectBuilder.SpringFramework/">here</a>.</p>
<p>Let me know what you think &#8211; especially if you can take the implementation to the point where it won&#8217;t need virtual properties to work <img src='http://www.udidahan.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2008/06/13/external-value-configuration-with-ioc/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Prism &#8211; Occasionally Connected?</title>
		<link>http://www.udidahan.com/2008/06/09/prism-occasionally-connected/</link>
		<comments>http://www.udidahan.com/2008/06/09/prism-occasionally-connected/#comments</comments>
		<pubDate>Mon, 09 Jun 2008 12:46:56 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Smart Client]]></category>
		<category><![CDATA[Threading]]></category>

		<guid isPermaLink="false">http://udidahan.weblogs.us/2008/06/09/prism-occasionally-connected/</guid>
		<description><![CDATA[Prism, AKA Composite Application Guidance + Composite Application Library, is rolling towards a release. I&#8217;ve been talking with Glenn Block quite a bit about Prism, and am even on the advisory board (what were they thinking?).
One of the topics not covered by Prism is occasional connectivity, and I would like to say a word or [...]]]></description>
			<content:encoded><![CDATA[<p>Prism, AKA Composite Application Guidance + Composite Application Library, is rolling towards a release. I&#8217;ve been talking with Glenn Block quite a bit about Prism, and am even on the advisory board (what were they thinking?).</p>
<p>One of the topics <em>not</em> covered by Prism is occasional connectivity, and I would like to say a word or two about that. First of all, if you&#8217;re building a standalone client (one that doesn&#8217;t communicate with anything), then there&#8217;s a good chance that Prism isn&#8217;t for you, although you could be composing other standalone client modules. So, if your client isn&#8217;t communicating with anything, well, then this post probably won&#8217;t interest you that much. Let&#8217;s start with&#8230;</p>
<h3>Physics<img style="border-right: 0px; border-top: 0px; margin: 0px 0px 10px 10px; border-left: 0px; border-bottom: 0px" height="192" alt="Physics" src="http://udidahan.weblogs.us/wp-content/uploads/image22.png" width="244" align="right" border="0"> </h3>
<p>Networks fail. Period. </p>
<p>This means that your client machine will not always be connected to other servers. </p>
<p>Also, servers fail &#8211; critical Windows patches and just regular power outages.</p>
<blockquote><p>Ergo, your &#8220;smart&#8221; client will be occasionally connected, whether you planned for it or not.</p>
</blockquote>
<p>And please don&#8217;t take this post as a &#8220;dumping on Prism&#8221; post &#8211; it isn&#8217;t intended that way. Rather, it is about how you should think about designing modules in Prism, and why.</p>
<h3>Modules and Connectivity</h3>
<p>Consider the case where we have two modules being composed in a single client. Each module communicates with a different server. Let&#8217;s call these modules Ma and Mb, and the servers Sa and Sb respectively. Now, let&#8217;s discuss what occurs given that the modules weren&#8217;t designed with occasional connectivity in mind.</p>
<blockquote><p>User clicks something in Mb which requires communication.</p>
<p>Mb tries to call Sb, say, over HTTP, using a regular web service invocation.</p>
<p>The calling thread, in this case, the one used for user interaction, is blocked waiting for a response from Sb.<a href="http://udidahan.weblogs.us/wp-content/uploads/image23.png"><img style="border-right: 0px; border-top: 0px; margin: 10px 0px 10px 10px; border-left: 0px; border-bottom: 0px" height="184" alt="image" src="http://udidahan.weblogs.us/wp-content/uploads/image-thumb19.png" width="244" align="right" border="0"></a></p>
<p>Sometime in this call, Sb fails, connectivity goes down, whatever. </p>
<p>30 seconds after the call, the HTTP connection times out.</p>
</blockquote>
<p>If something important were happening in Ma at the same time, the user couldn&#8217;t even <em>see</em> it, let alone do anything about it since the user interaction thread is stuck. This is a serious concern for the financial services domain, but in many others as well.</p>
<h3>You mean there&#8217;s more?</h3>
<p>I can go on, but I think that that&#8217;s enough to paint the picture that if you are building a smart client, there are a lot more things to think about than just learning Prism. That&#8217;s my main concern after witnessing what happened around the CAB. Given the learning curve around these frameworks many developers don&#8217;t seek to deepen their understanding beyond just becoming proficient with them. This isn&#8217;t just centered on the developers, evangelists in Microsoft tend to paint the picture this way:</p>
<blockquote><p>Once you understand X (CAB, Prism, BizTalk, whatever), all your problems are solved.</p>
</blockquote>
<p>That&#8217;s not to say there aren&#8217;t good things in those technologies, but that&#8217;s just it, they&#8217;re just <em>tools</em>. Silver hammers and &#8220;laser&#8221; guided saws do not a master carpenter make. There&#8217;s actually a pretty good chance the regular guy will saw their arm off.</p>
<h3>Help<a href="http://udidahan.weblogs.us/wp-content/uploads/image24.png"><img style="border-right: 0px; border-top: 0px; margin: 10px 0px 10px 10px; border-left: 0px; border-bottom: 0px" height="191" alt="image" src="http://udidahan.weblogs.us/wp-content/uploads/image-thumb20.png" width="244" align="right" border="0"></a></h3>
<p>I do hope more &#8220;instruction manuals&#8221; will be coming out of Microsoft on these topics. That&#8217;s not to say there aren&#8217;t any. Specifically on the topic of occasional connectivity, there is <a href="http://msdn.microsoft.com/en-us/library/ms998482.aspx">Chapter 4 of the Smart Client Architecture &amp; Design Guide</a>. Unfortunately, it doesn&#8217;t say anything about how that connects with the MVC/MVP being used client side (the bits affected by Prism). <a href="http://msdn.microsoft.com/en-us/library/ms998490.aspx">Chapter 6</a> of the same guide deals with the client-side threading, but doesn&#8217;t address issues like: </p>
<ul>
<li>Which model object instance are views bound to.</li>
<li>Do other threads have access to that object at the same time.</li>
<li>Which controller/presenter is responsible for giving that object to the view.</li>
<li>Do they need to clone it.</li>
<li>How deep should the clone be.</li>
<li>How do various controllers/presenters (which may be showing the same object in different views at the same time) communicate changes to their various independent clones.</li>
</ul>
<p>I haven&#8217;t yet documented all the patterns that answer these questions, but until I do (or Microsoft does), let me offer these few resources which I&#8217;ve put out over the years:</p>
<ul>
<li><a href="http://www.developer.com/design/article.php/3708006">Occasionally Connected Systems Architecture: The Client</a></li>
<li><a href="http://www.developer.com/design/article.php/3705396">Occasionally Connected Systems Architecture: Concurrency</a></li>
<li><a href="http://www.developer.com/design/article.php/3708006">Threading issues when smart clients reconnect</a></li>
<li>[Podcast] <a href="http://udidahan.weblogs.us/2007/04/17/podcast-occasionally-connected-smart-clients-and-adonet-sync-services/">Occasionally Connected Smart Clients and ADO.NET Sync Services</a></li>
</ul>
<p>There&#8217;s also some more links under the <a href="http://udidahan.weblogs.us/first-time-here/#smart_client">Smart Client link</a> of my <a href="http://udidahan.weblogs.us/first-time-here/">&#8220;First time here?&#8221; page</a>.</p>
<p>Also, please join me in asking Microsoft for an update to these guides &#8211; comments below or your own blog posts would be great.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2008/06/09/prism-occasionally-connected/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WCF, Smart Clients, and Deadlocks</title>
		<link>http://www.udidahan.com/2008/04/11/wcf-smart-clients-and-deadlocks/</link>
		<comments>http://www.udidahan.com/2008/04/11/wcf-smart-clients-and-deadlocks/#comments</comments>
		<pubDate>Fri, 11 Apr 2008 09:15:38 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[NServiceBus]]></category>
		<category><![CDATA[Simplicity]]></category>
		<category><![CDATA[Smart Client]]></category>
		<category><![CDATA[Threading]]></category>
		<category><![CDATA[WCF]]></category>

		<guid isPermaLink="false">http://udidahan.weblogs.us/2008/04/11/wcf-smart-clients-and-deadlocks/</guid>
		<description><![CDATA[There&#8217;s a new article up on MSDN describing how to write Smart Clients using WCF. The author is none other than WCF-Master Lowy and he goes over the multitude of ways you can deadlock yourself.
Here&#8217;s a taste:
UI Thread and Concurrency Management
Whenever you use hosting on the UI thread, deadlocks are possible. For example, the following [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s a new article up on MSDN describing how to write Smart Clients using WCF. The author is none other than <a href="http://www.idesign.net/">WCF-Master Lowy</a> and he goes over the multitude of ways you can deadlock yourself.</p>
<p>Here&#8217;s a taste:</p>
<blockquote><h3>UI Thread and Concurrency Management</h3>
<p>Whenever you use hosting on the UI thread, deadlocks are possible. For example, the following setup is guaranteed to result with a deadlock: A Windows Forms application is hosting a service with <b>UseSynchronizationContext</b> set to <b>true</b>, and UI thread affinity is established. The Windows Forms application then calls the service over one of its endpoints. The call to the service blocks the UI thread, while WCF posts a message to the UI thread to invoke the service. That message is never processed, because of the blocking UI thread—hence, the deadlock.
<p>Another possible case for a deadlock occurs when a Windows Forms application is hosting a service with <b>UseSynchronizationContext</b> set to <b>true</b> and UI thread affinity is established. The service receives a call from a remote client. That call is marshaled to the UI thread and is eventually executed on that thread. If the service is allowed to call out to another service, that can result in a deadlock if the callout causality tries somehow to update the UI or call back to the service’s endpoint, because all of the service instances that are associated with any endpoint (regardless of the service-instancing mode) share the same UI thread.
<p>Similarly, you risk a deadlock if the service is configured for reentrancy and it calls back to its client. You risk a deadlock if the callback causality tries to update the UI or enter the service, because that reentrance must be marshaled to the blocked UI thread.</p>
</blockquote>
<p>Actually, I have difficulty believing that Juval would go so far as to suggest that even the forms should be services, but he does:<br />
<blockquote>
<h3>Form as a Service</h3>
<p>The main motivation for hosting a WCF service on the UI thread is if the service must update the UI or the form. The problem is always: How does the service reach out and obtain a reference to the form? While the techniques and ideas that appear thus far in the listings certainly work, <font color="#800000" size="4"><strong><em>it would be simpler yet if the form were the service</em></strong></font> and hosted itself. For this to work, the form (or any window) must be a singleton service. The reason is that singleton is the only instancing mode that enables you to provide WCF with a live instance to host. In addition, you would not want a per-call form that exists only during a client call (which is usually very brief), nor would you want a per-session form that only a single client can establish a session with and update.
<p>When a form is also a service, <font color="#800000" size="4"><strong><em>having that form as a singleton service is the best instancing mode all around</em></strong></font>.</p>
</blockquote>
<p>I think that this article serves as a great treatise leading to only one conclusion &#8211; you&#8217;d have to be crazy to try to do this without some higher level framework, preferably with a different low-level framework too <img src='http://www.udidahan.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  . Sucks Microsoft didn&#8217;t put one out &#8211; nor is there a pending beta, CTP, or even word about some project with a codename handling this. From what I know about <a href="http://www.codeplex.com/prism">Prism</a>, it doesn&#8217;t intend to handle this issue either.
<p>One thing that isn&#8217;t covered in the article is that if you do choose not to tie the client-side service to the UI thread, you open yourself up to race conditions. Reasons you&#8217;d want to handle messages on a different thread center around UI responsiveness. I&#8217;ve written about these things before:
<ul>
<li>
<h4><a href="http://udidahan.weblogs.us/2007/12/06/object-builder-the-place-to-fix-system-wide-threading-bugs/">Object Builder &#8211; the place to fix system-wide threading bugs</a></h4>
</li>
<li>
<h4><a href="http://udidahan.weblogs.us/2007/12/07/eureka-aop-is-the-final-piece-of-the-multi-threaded-smart-client-puzzle/">Eureka! AOP is the final piece of the multi-threaded smart client puzzle</a></h4>
</li>
<li>
<h4><a href="http://udidahan.weblogs.us/2007/12/26/what-makes-smart-clients-safe/">What Makes Smart Clients Safe?</a></h4>
</li>
</ul>
<p>The more I read things like this, the more I feel that I have to get going with my nServiceBus based solution. I&#8217;m fairly swamped as it is, so if anyone is interested in helping get this project off the ground, I&#8217;d be most grateful &#8211; as I think anyone else that had to build a smart client would. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2008/04/11/wcf-smart-clients-and-deadlocks/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How to create fully encapsulated Domain Models</title>
		<link>http://www.udidahan.com/2008/02/29/how-to-create-fully-encapsulated-domain-models/</link>
		<comments>http://www.udidahan.com/2008/02/29/how-to-create-fully-encapsulated-domain-models/#comments</comments>
		<pubDate>Fri, 29 Feb 2008 14:40:33 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Business Rules]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[Data Access]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[OO]]></category>
		<category><![CDATA[Simplicity]]></category>

		<guid isPermaLink="false">http://udidahan.weblogs.us/2008/02/29/how-to-create-fully-encapsulated-domain-models/</guid>
		<description><![CDATA[ Update: The new and improved solution is now available: Domain Events, Take 2.
Most people getting started with DDD and the Domain Model pattern get stuck on this. For a while I tried answering this on the discussion groups, but here we have a nice example that I can point to next time.
The underlying problem [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://udidahan.weblogs.us/wp-content/uploads/image8.png"><img style="border-right: 0px; border-top: 0px; margin: 0px 10px; border-left: 0px; border-bottom: 0px" height="192" alt="image" src="http://udidahan.weblogs.us/wp-content/uploads/image-thumb6.png" width="150" align="right" border="0"></a> <b>Update:</b> The new and <i>improved</i> solution is now available: <a href="http://www.udidahan.com/2008/08/25/domain-events-take-2/">Domain Events, Take 2</a>.</p>
<p>Most people getting started with DDD and the Domain Model pattern get stuck on this. For a while I tried answering this on the discussion groups, but here we have a nice example that I can point to next time.</p>
<p>The underlying problem I&#8217;ve noticed over the past few years is that developers are still thinking in terms of querying when they need more data. When moving to the Domain Model pattern, you have to &#8220;simply&#8221; represent the domain concepts in code &#8211; in other words, see things you aren&#8217;t used to seeing. I&#8217;ll highlight that part in the question below so that you can see where I&#8217;m going to go with this in my answer:</p>
<blockquote><p>I have an instance where I believe I need access to a service or repository from my entity to evaluate a business rule but I&#8217;m using NHibernate for persistence so I don&#8217;t have a real good way to inject services into my entity. Can I get some viewpoints on just passing the services to my entity vs. using a facade?</p>
<p>Let me explain my problem to provide more context to the problem.</p>
<p>The core domain revolves around renting video games. I am working on a new feature to allow customers to trade in old video games. <font color="#ff0000">Customers</font> can trade in multiple games at a time so we have a TradeInCart entity that works similar to most shopping carts that everybody is familiar with. However there are several rules that limit the items that can be placed into the TradeInCart. The core rules are:</p>
<p>1. Only 3 games of the same title can be added to the cart.<br />2. The total number of items in the cart cannot exceed 10.<br />3. No games can be added to the cart that the <font color="#ff0000">customer had previously reported lost</font> with regards to their rental membership.<br />&nbsp;&nbsp;&nbsp; a. If an attempt is made to add a previously reported lost game, then we need to log a BadQueueStatusAddAttempt to the persistence store.</p>
<p>So the first 2 rules are easily handled internally by the cart through an Add operation. Sample cart interface is below.</p>
<p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">class</span> TradeInCart{</pre>
<pre><span class="lnum">   2:  </span>    Account Account{get;}</pre>
<pre class="alt"><span class="lnum">   3:  </span>    LineItem Add(Game game);</pre>
<pre><span class="lnum">   4:  </span>    ValidationResult CanAdd(Game game);</pre>
<pre class="alt"><span class="lnum">   5:  </span>    IList&lt;LineItems&gt; LineItems{get;}</pre>
<pre><span class="lnum">   6:  </span>}</pre>
</div>
<p>However the #3 rule is much more complicated and can&#8217;t be handled internally by the cart, so I have to depend on external services. Splitting up the validation logic for a cart add operation doesn&#8217;t seem very appealing to me at all. So I have the option of passing in a repository to get the previously reported lost games and a service to log bad attempts. This makes my cart interface ugly real quick.</p>
<p><div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">class</span> TradeInCart{</pre>
<pre><span class="lnum">   2:  </span>    Account Account{get;}</pre>
<pre class="alt"><span class="lnum">   3:  </span>    LineItem Add(</pre>
<pre><span class="lnum">   4:  </span>        Game game, </pre>
<pre class="alt"><span class="lnum">   5:  </span>        IRepository&lt;QueueHistory&gt; repository, </pre>
<pre><span class="lnum">   6:  </span>        LoggingService service);</pre>
<pre class="alt"><span class="lnum">   7:  </span>&nbsp;</pre>
<pre><span class="lnum">   8:  </span>    ValidationResult CanAdd(</pre>
<pre class="alt"><span class="lnum">   9:  </span>        Game game, </pre>
<pre><span class="lnum">  10:  </span>        IRepository&lt;QueueHistory&gt; repository, </pre>
<pre class="alt"><span class="lnum">  11:  </span>        LoggingService service);</pre>
<pre><span class="lnum">  12:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  13:  </span>    IList&lt;LineItems&gt; LineItems{get;}</pre>
<pre><span class="lnum">  14:  </span>}</pre>
</div>
<p>The alternative option is to have a TradeInCartFacade that handles the validations and adding the items to the cart. The façade can have the repository and services injected though DI which is nice, but the big negative is that the cart ends up totally anemic.</p>
<p>Any thought on this would be greatly appreciated.</p>
<p>Thanks,<br />Jesse</p>
</blockquote>
<p>As I highlighted above, the thing that will help you with your business rules is to introduce the Customer object (that you probably already have) with the property GamesReportedLost (an IList&lt;Game&gt;). Your TradeInCart would have a reference to the Customer object and could then check the rule in the Add method.</p>
<p>Before I go into the code, it looks like your Account object might be used the same way, but your description of the domain doesn&#8217;t mention accounts, so I&#8217;m going to assume that that&#8217;s unrelated for now:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">public class</span> Customer{</pre>
<pre><span class="lnum">   2:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">   3:  </span>    <span class="rem">/* other properties and methods */</span></pre>
<pre><span class="lnum">   4:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">   5:  </span>    <span class="kwrd">private</span> IList&lt;Game&gt; gamesReportedLost;</pre>
<pre><span class="lnum">   6:  </span>    <span class="kwrd">public</span> <span class="kwrd">virtual</span> IList&lt;Game&gt; GamesReportedLost </pre>
<pre class="alt"><span class="lnum">   7:  </span>    { </pre>
<pre><span class="lnum">   8:  </span>        get</pre>
<pre class="alt"><span class="lnum">   9:  </span>        {</pre>
<pre><span class="lnum">  10:  </span>            <span class="kwrd">return</span> gamesReportedLost;</pre>
<pre class="alt"><span class="lnum">  11:  </span>        }</pre>
<pre><span class="lnum">  12:  </span>        set</pre>
<pre class="alt"><span class="lnum">  13:  </span>        {</pre>
<pre><span class="lnum">  14:  </span>            gamesReportedLost = <span class="kwrd">value</span>;</pre>
<pre class="alt"><span class="lnum">  15:  </span>        }</pre>
<pre><span class="lnum">  16:  </span>    }</pre>
<pre class="alt"><span class="lnum">  17:  </span>}</pre>
</div>
<p>Keep in mind that the GamesReportedLost is a persistent property of Customer. Every time a customer reports a game lost, this list needs to be kept up to date. Here&#8217;s the TradeInCart now:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">public</span> <span class="kwrd">class</span> TradeInCart</pre>
<pre><span class="lnum">   2:  </span>{</pre>
<pre class="alt"><span class="lnum">   3:  </span>    <span class="rem">/* other properties and methods */</span></pre>
<pre><span class="lnum">   4:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">   5:  </span>    <span class="kwrd">private</span> Customer customer;</pre>
<pre><span class="lnum">   6:  </span>    <span class="kwrd">public</span> <span class="kwrd">virtual</span> Customer Customer</pre>
<pre class="alt"><span class="lnum">   7:  </span>    { </pre>
<pre><span class="lnum">   8:  </span>        get { <span class="kwrd">return</span> customer; }</pre>
<pre class="alt"><span class="lnum">   9:  </span>        set { customer = <span class="kwrd">value</span>; }</pre>
<pre><span class="lnum">  10:  </span>    }</pre>
<pre class="alt"><span class="lnum">  11:  </span>&nbsp;</pre>
<pre><span class="lnum">  12:  </span>    <span class="kwrd">private</span> IList&lt;LineItem&gt; lineItems;</pre>
<pre class="alt"><span class="lnum">  13:  </span>    <span class="kwrd">public</span> <span class="kwrd">virtual</span> IList&lt;LineItem&gt; LineItems</pre>
<pre><span class="lnum">  14:  </span>    {</pre>
<pre class="alt"><span class="lnum">  15:  </span>        get { <span class="kwrd">return</span> lineItems; }</pre>
<pre><span class="lnum">  16:  </span>        set { lineItems = <span class="kwrd">value</span>; }</pre>
<pre class="alt"><span class="lnum">  17:  </span>    }</pre>
<pre><span class="lnum">  18:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  19:  </span>    <span class="kwrd">public</span> <span class="kwrd">void</span> Add(Game game)</pre>
<pre><span class="lnum">  20:  </span>    {</pre>
<pre class="alt"><span class="lnum">  21:  </span>        <span class="kwrd">if</span> (lineItems.Count &gt;= CONSTANTS.MaxItemsPerCart)</pre>
<pre><span class="lnum">  22:  </span>        {</pre>
<pre class="alt"><span class="lnum">  23:  </span>            FailureEvents.RaiseCartIsFullEvent();</pre>
<pre><span class="lnum">  24:  </span>            <span class="kwrd">return</span>;</pre>
<pre class="alt"><span class="lnum">  25:  </span>        }</pre>
<pre><span class="lnum">  26:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  27:  </span>        <span class="kwrd">if</span> (NumberOfGameAlreadyInCart(game) &gt;=</pre>
<pre><span class="lnum">  28:  </span>            CONSTANTS.MaxNumberOfSameGamePerCart)</pre>
<pre class="alt"><span class="lnum">  29:  </span>        {</pre>
<pre><span class="lnum">  30:  </span>            FailureEvents</pre>
<pre class="alt"><span class="lnum">  31:  </span>              .RaiseMaxNumberOfSameGamePerCartReachedEvent();</pre>
<pre><span class="lnum">  32:  </span>            <span class="kwrd">return</span>;</pre>
<pre class="alt"><span class="lnum">  33:  </span>        }</pre>
<pre><span class="lnum">  34:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  35:  </span>        <span class="kwrd">if</span> (customer.GamesReportedLost.Contains(game))</pre>
<pre><span class="lnum">  36:  </span>            FailureEvents.RaiseGameReportedLostEvent();</pre>
<pre class="alt"><span class="lnum">  37:  </span>        <span class="kwrd">else</span></pre>
<pre><span class="lnum">  38:  </span>            <span class="kwrd">this</span>.lineItems.Add(<span class="kwrd">new</span> LineItem(game));</pre>
<pre class="alt"><span class="lnum">  39:  </span>    }</pre>
<pre><span class="lnum">  40:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  41:  </span>    <span class="kwrd">private</span> <span class="kwrd">int</span> NumberOfGameAlreadyInCart(Game game)</pre>
<pre><span class="lnum">  42:  </span>    {</pre>
<pre class="alt"><span class="lnum">  43:  </span>        <span class="kwrd">int</span> result = 0;</pre>
<pre><span class="lnum">  44:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  45:  </span>        <span class="kwrd">foreach</span>(LineItem li <span class="kwrd">in</span> <span class="kwrd">this</span>.lineItems)</pre>
<pre><span class="lnum">  46:  </span>            <span class="kwrd">if</span> (li.Game == game)</pre>
<pre class="alt"><span class="lnum">  47:  </span>                result++;</pre>
<pre><span class="lnum">  48:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  49:  </span>        <span class="kwrd">return</span> result;</pre>
<pre><span class="lnum">  50:  </span>    }</pre>
<pre class="alt"><span class="lnum">  51:  </span>}</pre>
<pre><span class="lnum">  52:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  53:  </span><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">class</span> FailureEvents</pre>
<pre><span class="lnum">  54:  </span>{</pre>
<pre class="alt"><span class="lnum">  55:  </span>    <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">event</span> EventHandler GameReportedLost;</pre>
<pre><span class="lnum">  56:  </span>    <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> RaiseGameReportedLostEvent()</pre>
<pre class="alt"><span class="lnum">  57:  </span>    {</pre>
<pre><span class="lnum">  58:  </span>         <span class="kwrd">if</span> (GameReportedLost != <span class="kwrd">null</span>)</pre>
<pre class="alt"><span class="lnum">  59:  </span>             GameReportedLost(<span class="kwrd">null</span>, <span class="kwrd">null</span>);</pre>
<pre><span class="lnum">  60:  </span>    }</pre>
<pre class="alt"><span class="lnum">  61:  </span>&nbsp;</pre>
<pre><span class="lnum">  62:  </span>    <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">event</span> EventHandler CartIsFull;</pre>
<pre class="alt"><span class="lnum">  63:  </span>    <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> RaiseCartIsFullEvent()</pre>
<pre><span class="lnum">  64:  </span>    {</pre>
<pre class="alt"><span class="lnum">  65:  </span>         <span class="kwrd">if</span> (CartIsFull != <span class="kwrd">null</span>)</pre>
<pre><span class="lnum">  66:  </span>             CartIsFull(<span class="kwrd">null</span>, <span class="kwrd">null</span>);</pre>
<pre class="alt"><span class="lnum">  67:  </span>    }</pre>
<pre><span class="lnum">  68:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  69:  </span>    <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">event</span> EventHandler MaxNumberOfSameGamePerCartReached;</pre>
<pre><span class="lnum">  70:  </span>    <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> RaiseMaxNumberOfSameGamePerCartReachedEvent()</pre>
<pre class="alt"><span class="lnum">  71:  </span>    {</pre>
<pre><span class="lnum">  72:  </span>         <span class="kwrd">if</span> (MaxNumberOfSameGamePerCartReached != <span class="kwrd">null</span>)</pre>
<pre class="alt"><span class="lnum">  73:  </span>             MaxNumberOfSameGamePerCartReached(<span class="kwrd">null</span>, <span class="kwrd">null</span>);</pre>
<pre><span class="lnum">  74:  </span>    }</pre>
<pre class="alt"><span class="lnum">  75:  </span>}</pre>
</div>
<p><a href="http://udidahan.weblogs.us/wp-content/uploads/image9.png"><img style="border-right: 0px; border-top: 0px; margin: 0px 10px; border-left: 0px; border-bottom: 0px" height="244" alt="image" src="http://udidahan.weblogs.us/wp-content/uploads/image-thumb7.png" width="184" align="right" border="0"></a> Your service layer class that calls the Add method of TradeInCart would first subscribe to the relevant events in FailureEvents. If one of those events is raised, it would do the necessary logging, external system calls, etc.</p>
<p>As you can see, the API of TradeInCart doesn&#8217;t need to make use of any external repositories, nor do you need to inject any other external dependencies in.</p>
<p>One thing I didn&#8217;t do in the above code to keep it &#8220;short&#8221; is to define the relevant custom EventArgs for bubbling up the information as to <em>which</em> game was reported lost or already have 3 of those in the cart. That is something that definitely should be done so that the service layer can pass this information back to the client.</p>
<p>Here&#8217;s a look at Service Layer code:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:  </span><span class="kwrd">public</span> <span class="kwrd">class</span> AddGameToCartMessageHandler :</pre>
<pre><span class="lnum">   2:  </span>    BaseMessageHandler&lt;AddGameToCartMessage&gt;</pre>
<pre class="alt"><span class="lnum">   3:  </span>{</pre>
<pre><span class="lnum">   4:  </span>    <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Handle(AddGameToCartMessage m)</pre>
<pre class="alt"><span class="lnum">   5:  </span>    {</pre>
<pre><span class="lnum">   6:  </span>        <span class="kwrd">using</span> (ISession session = SessionFactory.OpenSession())</pre>
<pre class="alt"><span class="lnum">   7:  </span>        <span class="kwrd">using</span> (ITransaction tx = session.BeginTransaction())</pre>
<pre><span class="lnum">   8:  </span>        {</pre>
<pre class="alt"><span class="lnum">   9:  </span>            TradeInCart cart = session.Get&lt;TradeInCart&gt;(m.CartId);</pre>
<pre><span class="lnum">  10:  </span>            Game g = session.Get&lt;Game&gt;(m.GameId);</pre>
<pre class="alt"><span class="lnum">  11:  </span>&nbsp;</pre>
<pre><span class="lnum">  12:  </span>            Domain.FailureEvents.GameReportedLost +=</pre>
<pre class="alt"><span class="lnum">  13:  </span>              gameReportedLost;</pre>
<pre><span class="lnum">  14:  </span>            Domain.FailureEvents.CartIsFull +=</pre>
<pre class="alt"><span class="lnum">  15:  </span>              cartIsFull;</pre>
<pre><span class="lnum">  16:  </span>            Domain.FailureEvents.MaxNumberOfSameGamePerCartReached +=</pre>
<pre class="alt"><span class="lnum">  17:  </span>              maxNumberOfSameGamePerCartReached;</pre>
<pre><span class="lnum">  18:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  19:  </span>            cart.Add(g);</pre>
<pre><span class="lnum">  20:  </span>&nbsp;</pre>
<pre class="alt"><span class="lnum">  21:  </span>            Domain.FailureEvents.GameReportedLost -=</pre>
<pre><span class="lnum">  22:  </span>              gameReportedLost;</pre>
<pre class="alt"><span class="lnum">  23:  </span>            Domain.FailureEvents.CartIsFull -=</pre>
<pre><span class="lnum">  24:  </span>              cartIsFull;</pre>
<pre class="alt"><span class="lnum">  25:  </span>            Domain.FailureEvents.MaxNumberOfSameGamePerCartReached -=</pre>
<pre><span class="lnum">  26:  </span>              maxNumberOfSameGamePerCartReached;</pre>
<pre class="alt"><span class="lnum">  27:  </span>&nbsp;</pre>
<pre><span class="lnum">  28:  </span>            tx.Commit();</pre>
<pre class="alt"><span class="lnum">  29:  </span>        }</pre>
<pre><span class="lnum">  30:  </span>    }</pre>
<pre class="alt"><span class="lnum">  31:  </span>&nbsp;</pre>
<pre><span class="lnum">  32:  </span>    <span class="kwrd">private</span> EventHandler gameReportedLost = <span class="kwrd">delegate</span> { </pre>
<pre class="alt"><span class="lnum">  33:  </span>          Bus.Return((<span class="kwrd">int</span>)ErrorCodes.GameReportedLost);</pre>
<pre><span class="lnum">  34:  </span>        };</pre>
<pre class="alt"><span class="lnum">  35:  </span>&nbsp;</pre>
<pre><span class="lnum">  36:  </span>    <span class="kwrd">private</span> EventHandler cartIsFull = <span class="kwrd">delegate</span> { </pre>
<pre class="alt"><span class="lnum">  37:  </span>          Bus.Return((<span class="kwrd">int</span>)ErrorCodes.CartIsFull);</pre>
<pre><span class="lnum">  38:  </span>        };</pre>
<pre class="alt"><span class="lnum">  39:  </span>&nbsp;</pre>
<pre><span class="lnum">  40:  </span>    <span class="kwrd">private</span> EventHandler maxNumberOfSameGamePerCartReached = <span class="kwrd">delegate</span> { </pre>
<pre class="alt"><span class="lnum">  41:  </span>          Bus.Return((<span class="kwrd">int</span>)ErrorCodes.MaxNumberOfSameGamePerCartReached);</pre>
<pre><span class="lnum">  42:  </span>        };</pre>
<pre class="alt"><span class="lnum">  43:  </span>    }</pre>
<pre><span class="lnum">  44:  </span>}</pre>
</div>
<p><img style="margin: 0px 10px 5px" src="http://www.familyportraitpainting.com/images/grandfather_sample.jpg" align="right">It&#8217;s important to remember to clean up your event subscriptions so that your Service Layer objects get garbage collected. This is one of the primary causes of memory leaks when using static events in your Domain Model. I&#8217;m hoping to find ways to use lambdas to decrease this repetitive coding pattern. You might be thinking to yourself that non-static events on your Domain Model objects would be easier, since those objects would get collected, freeing up the service layer objects for collection as well. There&#8217;s just on small problem:</p>
<p>The problem is that if an event is raised by a child (or grandchild object), the service layer object may not even know that that grandchild was involved and, as such, would not have subscribed to that event. The only way the service layer could work was by knowing how the Domain Model worked internally &#8211; in essence, breaking encapsulation.</p>
<p>If you&#8217;re thinking that using exceptions would be better, you&#8217;d be right in thinking that that won&#8217;t break encapsulation, <em>and</em> that you wouldn&#8217;t need all that subscribe/unsubscribe code in the service layer. The only problem is that the Domain Model needs to know that the service layer had a default catch clause so that it wouldn&#8217;t blow up. Otherwise, the service layer (or WCF, or nServiceBus) may end up flagging that message as a poison message (<a href="http://udidahan.weblogs.us/2007/02/15/it%e2%80%99s-poison-i-tell-you-poison/">Read more about poison messages</a>). You&#8217;d also have to be extremely careful about in which environments you used your Domain Model &#8211; in other words, your reuse is shot. </p>
<h3>Conclusion</h3>
<p>I never said it would be easy <img src='http://www.udidahan.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>However, the solution is simple (not complex). The same patterns occur over and over. The design is consistent. By focusing on the dependencies we now have a domain model that is reusable across many environments (server, client, sql clr, silverlight). The domain model is also testable without resorting to any fancy mock objects.</p>
<p>One closing comment &#8211; while I do my best to write code that is consistent with production quality environments, this code is more about demonstrating design principles. As such, I focus more on the self-documenting aspects of the code and have elided many production concerns. </p>
<p>Do you have a better solution? </p>
<p>Something that I haven&#8217;t considered?</p>
<p>Do me a favour &#8211; leave me a comment. Tell me what you think.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2008/02/29/how-to-create-fully-encapsulated-domain-models/feed/</wfw:commentRss>
		<slash:comments>59</slash:comments>
		</item>
		<item>
		<title>From CRUD to Domain-Driven Fluency</title>
		<link>http://www.udidahan.com/2008/02/15/from-crud-to-domain-driven-fluency/</link>
		<comments>http://www.udidahan.com/2008/02/15/from-crud-to-domain-driven-fluency/#comments</comments>
		<pubDate>Fri, 15 Feb 2008 15:58:19 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[ADO.NET]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[Data Access]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[OO]]></category>
		<category><![CDATA[Simplicity]]></category>

		<guid isPermaLink="false">http://udidahan.weblogs.us/2008/02/15/from-crud-to-domain-driven-fluency/</guid>
		<description><![CDATA[I got a question about how to stay away from CRUD based service interfaces when the logic itself is like that, and I’ve found that this shift in thinking really needs more examples, so I’ve decided to put this out there:

For instance, in an HR system, the process of interviewing candidates &#8211; wouldn’t you just [...]]]></description>
			<content:encoded><![CDATA[<p>I got a question about how to stay away from CRUD based service interfaces when the logic itself is like that, and I’ve found that this shift in thinking really needs more examples, so I’ve decided to put this out there:<br />
<blockquote>
<p>For instance, in an HR system, the process of interviewing candidates &#8211; wouldn’t you just insert, update, and delete these Appointment objects?</p>
</blockquote>
<p>If I were to put on my domain-driven hat, I would describe those requirements differently – interview appointments have a lifecycle: proposed, accepted, cancelled, etc. It seems that only a user of the role HR Interviewer should be able to make appointments for themselves, so the service layer code would probably look something like this:
<p><!-- code formatted by http://manoli.net/csharpformat/ --><br />
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}</p>
<p>.csharpcode pre { margin: 0em; }</p>
<p>.csharpcode .rem { color: #008000; }</p>
<p>.csharpcode .kwrd { color: #0000ff; }</p>
<p>.csharpcode .str { color: #006080; }</p>
<p>.csharpcode .op { color: #0000c0; }</p>
<p>.csharpcode .preproc { color: #cc6633; }</p>
<p>.csharpcode .asp { background-color: #ffff00; }</p>
<p>.csharpcode .html { color: #800000; }</p>
<p>.csharpcode .attr { color: #ff0000; }</p>
<p>.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}</p>
<p>.csharpcode .lnum { color: #606060; }
</style>
<pre class="csharpcode"><span class="kwrd">using</span> (ISession session = SessionFactory.OpenSession())
<span class="kwrd">using</span> (ITransaction tx = session.BeginTransaction())
{
    ICandidateInterviewer interviewer = session.Get&lt;ICandidateInterviewer&gt;(message.InterviewerId);
    ICandidate candidate = session.Get&lt;ICandidate&gt;(message.CandidateId);

    interviewer.ScheduleInterviewWith(candidate).At(message.RequestedTime);
    tx.Commit();
}
</pre>
<p>The “ScheduleInterviewWith” method accepts an ICandidate and returns an IAppointment. IAppointment has a method “At” which accepts a DateTime parameter and returns void – just changes the data of the appointment. The state of the appointment at creation time would probably be proposed. The appointment object would probably be added to the list of appointments for that interviewer – that’s what will cause it to be persisted automatically. </p>
<p>Later, when the candidate accepts the meeting, we could have the following method on ICandidate – void Accept(IAppointment); that would obviously check that the candidate is the right person for that interview, the appointment’s current state (not cancelled), etc – finally updating its state. What part of this looks like create, update, delete? If that’s what your service layer to domain interaction looks like, do you now know what your messages will be looking like?CRUD seems to be what most of us are familiar with. Moving to domain-driven thinking takes time and practice, but is well worth it. Contrast this with a more traditional O/R mapping solution: </p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}</p>
<p>.csharpcode pre { margin: 0em; }</p>
<p>.csharpcode .rem { color: #008000; }</p>
<p>.csharpcode .kwrd { color: #0000ff; }</p>
<p>.csharpcode .str { color: #006080; }</p>
<p>.csharpcode .op { color: #0000c0; }</p>
<p>.csharpcode .preproc { color: #cc6633; }</p>
<p>.csharpcode .asp { background-color: #ffff00; }</p>
<p>.csharpcode .html { color: #800000; }</p>
<p>.csharpcode .attr { color: #ff0000; }</p>
<p>.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}</p>
<p>.csharpcode .lnum { color: #606060; }
</style>
<pre class="csharpcode"><span class="kwrd">using</span> (ISession session = SessionFactory.OpenSession())
<span class="kwrd">using</span> (ITransaction tx = session.BeginTransaction())
{
    ICandidateInterviewer interviewer = session.Get&lt;ICandidateInterviewer&gt;(message.InterviewerId);
    ICandidate candidate = session.Get&lt;ICandidate&gt;(message.CandidateId); 

    Appointment a = <span class="kwrd">new</span> Appointment(); 

    a.Interviewer = interviewer;
    interviewer.Appointments.Add(a); 

    a.Candidate = candidate;
    candidate.Appointments.Add(a); 

    a.Time = message.RequestedTime; 

    session.Save(a);  

    tx.Commit();
} 
</pre>
<p>As you can see, we’ve got simpler, more expressive, and more testable code when employing the domain model pattern, than using “just” O/R mapping. I’m not saying that the domain model pattern doesn’t need O/R mapping in the background for it to work. But that’s just it &#8211; the persistence gunk needs to be in the background and the business logic needs to be encapsulated. </p>
<p>So, while I’ll agree with Dave that the Domain Model is <a href="http://laribee.com/blog/2007/05/08/domain-model-less-pattern-more-lifestyle/">more lifestyle than pattern</a>, I would argue against these conclusions: </p>
<blockquote>
<p>If this post had a point, it’s only to share the idea that Domain Model is a big, big thing. It’s probably overkill in a lot of cases where you have simple applications that have very simple purposes.</p>
</blockquote>
<p>As you just saw in the example above, there is no “overkill” to be seen. The domain model in the example wasn’t “a big, big thing”. </p>
<p>The domain model. Use it. </p>
<p>Why not have a better lifestyle?&nbsp;&nbsp; <img alt=";-)" src="http://udidahan.weblogs.us/wp-includes/images/smilies/icon_wink.gif"></p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2008/02/15/from-crud-to-domain-driven-fluency/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>WCF Everywhere? Not on my watch.</title>
		<link>http://www.udidahan.com/2007/12/29/wcf-everywhere-not-on-my-watch/</link>
		<comments>http://www.udidahan.com/2007/12/29/wcf-everywhere-not-on-my-watch/#comments</comments>
		<pubDate>Sat, 29 Dec 2007 15:00:19 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[WCF]]></category>

		<guid isPermaLink="false">http://udidahan.weblogs.us/2007/12/29/wcf-everywhere-not-on-my-watch/</guid>
		<description><![CDATA[ The other day I was at Juval&#8217;s presentation where the main message was WCF is a better .NET. In other words, if you use WCF on every one of your classes, you&#8217;ll benefit. I don&#8217;t know about you, but I&#8217;m quite wary of silver bullets &#8211; they tend to inflict quite a bit of [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://udidahan.weblogs.us/wp-content/uploads/silver_bullets.png" alt="silver bullets" style="border: 0px none ; margin: 0px 20px 20px" align="right" border="0" height="139" width="98" /></a> The other day I was at <a href="http://www.idesign.net/">Juval&#8217;s</a> presentation where the main message was WCF is a better .NET. In other words, if you use WCF on every one of your classes, you&#8217;ll benefit. I don&#8217;t know about you, but I&#8217;m quite wary of silver bullets &#8211; they tend to inflict quite a bit of pain when used indiscriminately. This post is my response to all the people who came up to me at the end of the presentation and wanted to know if I agreed with these far-reaching architectural statements.</p>
<p><a href="http://udidahan.weblogs.us/wp-content/uploads/oz1.jpg"><img src="http://udidahan.weblogs.us/wp-content/uploads/oz-thumb1.jpg" alt="oz" style="border: 0px none ; margin: 0px 20px 20px 0px" align="left" border="0" height="137" width="134" /></a>  First of all let me say that Juval is indeed a master presenter. The &#8220;looks like a class, walks like a class, quacks like a class&#8221; bit was excellent. I could tell that most people didn&#8217;t notice the speedy hands quickly deleting all attributes from the classes before the &#8220;looks like a class&#8230;&#8221; bit. At times, I got flashbacks from the Wizard of Oz &#8211; &#8220;pay no attention to the man behind the curtain&#8221;. If all attributes in WCF only went on the interfaces, then this might actually fly, but we all know that that&#8217;s not the case.</p>
<p>One of the interesting comparisons Juval made with WCF was the introduction of .NET. Few people in the audience seemed to remember (or maybe were just professionally younger than .NET&#8217;s 8 years), but when it came out .NET was marketed as being mainly about XML Web Services. Juval stated that this was done to play down the fact that .NET made the previous Windows programming technologies obsolete. He then drew the same conclusion about WCF &#8211; that it&#8217;s as much .NET 3.0 as .NET was the next version of MFC; besides being written in a language that resembles the previous technology, it&#8217;s really all different. I don&#8217;t think that anyone would argue the difference, but is it really a &#8220;plain .NET&#8221; killer?</p>
<p><a title="answer" name="answer"></a>The answer seemed to come around the overhead of WCF &#8211; yet Juval deftly deflected that issue with a demo showing WCF doing 200 calls a second. And everybody just bought it &#8211; I was shocked. That&#8217;s 5ms per call. If you actually take Juval&#8217;s advice and use WCF on all your classes, you&#8217;ve bought yourself one hell of a performance nightmare. Say you have around 20 of your objects involved in a sequence to handle a user action &#8211; not that many actually. With a 5ms lag per object interaction, that user action is going to take 100ms &#8211; not including any database or webservice stuff you might be doing. If you do that in a server environment, you&#8217;ll be doing roughly 10 concurrent users per core. And that&#8217;s not even doing any heavy calculations or anything. Moderately sized systems are running upwards of 1000 concurrent users &#8211; if they needed 100 cores (or dozens of servers) for that, I&#8217;m guessing that they&#8217;d be out of business.</p>
<p>Let&#8217;s cut this short &#8211; WCF everywhere doesn&#8217;t scale, doesn&#8217;t perform, isn&#8217;t maintainable, or testable either. In other words &#8211; don&#8217;t do it. I know Juval is a brilliant guy, and an amazing presenter &#8211; but I don&#8217;t believe he would be employing this with his own clients. This actually bears repeating. WCF is a fine technology for your application&#8217;s boundaries, but don&#8217;t be pushing it in.</p>
<h1>Don&#8217;t do it.</h1>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2007/12/29/wcf-everywhere-not-on-my-watch/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>ASP.NET Async pages and tasks now supported by nServiceBus</title>
		<link>http://www.udidahan.com/2007/12/18/aspnet-async-pages-and-tasks-now-supported-by-nservicebus/</link>
		<comments>http://www.udidahan.com/2007/12/18/aspnet-async-pages-and-tasks-now-supported-by-nservicebus/#comments</comments>
		<pubDate>Tue, 18 Dec 2007 23:57:08 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[NServiceBus]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Presentations]]></category>

		<guid isPermaLink="false">http://udidahan.weblogs.us/2007/12/18/aspnet-async-pages-and-tasks-now-supported-by-nservicebus/</guid>
		<description><![CDATA[I&#8217;ve been getting quite a few requests to support the asynchronous programming model exposed by ASP.NET 2.0 to enable the higher levels of scalability afforded by its IO completion ports. Well, nServiceBus now supports it. You can find a sample in the &#8220;Samples&#8221; that demonstrates how to use PageAsyncTasks to complete work asynchronously.
If you&#8217;re interested in [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been getting quite a few requests to support the <a href="http://www.google.com/url?sa=t&amp;ct=res&amp;cd=1&amp;url=http%3A%2F%2Fmsdn.microsoft.com%2Fmsdnmag%2Fissues%2F05%2F10%2FWickedCode%2F&amp;ei=W1toR7qyDZfuwwHP27XZDQ&amp;usg=AFQjCNEiK65cU0ETSr0LVSoYkxg-wVCB1g&amp;sig2=MaOGPGOVFpG3Rbk4T-mdNw">asynchronous programming model </a>exposed by ASP.NET 2.0 to enable the higher levels of scalability afforded by its IO completion ports. Well, <a href="http://www.nServiceBus.com">nServiceBus</a> now supports it. You can find a sample in the &#8220;Samples&#8221; that demonstrates how to use PageAsyncTasks to complete work asynchronously.</p>
<p>If you&#8217;re interested in getting a kick-start with nServiceBus, I&#8217;ll be presenting a full day tutorial on it at <a href="http://qcon.infoq.com/london/conference/">QCon in London</a> on March 11th. <a href="http://qcon.infoq.com/london/presentation/Build+Scalable%2C+Maintainable%2C+Distributed+Enterprise+.NET+Solutions+with+nServiceBus">Here </a>are the full details :</p>
<p><strong>Title</strong>:</p>
<p>Build Scalable, Maintainable, Distributed Enterprise .NET Solutions with nServiceBus</p>
<p><strong>Description</strong>:</p>
<p>Despite the recent flood of technologies and releases, distributed enterprise .net solution development remains as hard as ever.</p>
<p>WCF and WF provide valuable runtime components, yet still leave open the risk of developers using the wrong combination of options and ending up with an unscalable solution.</p>
<p>In this tutorial, developers will learn the specific patterns necessary to achieve scalability, as well as use supporting open-source frameworks to enable parallel development (and debugging!) of service interfaces, layers, and domain models.</p>
<p>After delving in to asynchronous message design, long-running workflow state management, and transaction-boundary placement developers will be able to design, debug, and deploy their specific distributed systems.</p>
<p>&#8212;</p>
<p>Hope to see you there.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2007/12/18/aspnet-async-pages-and-tasks-now-supported-by-nservicebus/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Eureka! AOP is the final piece of the multi-threaded smart client puzzle</title>
		<link>http://www.udidahan.com/2007/12/07/eureka-aop-is-the-final-piece-of-the-multi-threaded-smart-client-puzzle/</link>
		<comments>http://www.udidahan.com/2007/12/07/eureka-aop-is-the-final-piece-of-the-multi-threaded-smart-client-puzzle/#comments</comments>
		<pubDate>Fri, 07 Dec 2007 23:01:50 +0000</pubDate>
		<dc:creator>thesoftwaresimplist</dc:creator>
				<category><![CDATA[AOP]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Dependency Injection]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[NServiceBus]]></category>
		<category><![CDATA[Smart Client]]></category>
		<category><![CDATA[Threading]]></category>

		<guid isPermaLink="false">http://udidahan.weblogs.us/2007/12/07/eureka-aop-is-the-final-piece-of-the-multi-threaded-smart-client-puzzle/</guid>
		<description><![CDATA[If you&#8217;ve read my recent post on the threading issues I&#8217;ve been dealing with in Smart Client Applications, then you&#8217;re probably beginning to get the picture that its fairly complex. To tell you the truth, it is. And up until this point I haven&#8217;t been able to find anything that&#8217;ll help &#8211; and that includes [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve read my recent post on the <a href="http://udidahan.weblogs.us/2007/12/06/object-builder-the-place-to-fix-system-wide-threading-bugs/">threading issues I&#8217;ve been dealing with in Smart Client Applications</a>, then you&#8217;re probably beginning to get the picture that its fairly complex. To tell you the truth, it is. And up until this point I haven&#8217;t been able to find anything that&#8217;ll help &#8211; and that includes the CAB/SCSF. But yesterday I had my epiphany. The answer was in AOP.</p>
<p>You see, the main problem that I hadn&#8217;t been able to solve was that in order for the code to be thread-safe, you had to make sure that no code in the views would/could change entity data. One solution is not to use data-binding, which sucks, but isn&#8217;t enough to be sure. Another solution is to have all supervising-controllers clone an entity before they give it to a view. Even if you could possibly code review every line of those classes, the new guy (or old guy who forgot) will, by accident, write one new line of code that could pass an entity to a view without cloning it first. That&#8217;s not a very sustainable solution.</p>
<p>This thing has been bothering me for a couple of months now and I hadn&#8217;t found a way around it. Until yesterday, like I said. I was talking to somebody about threading stuff, and somehow my unconscience lobbed me this thought about AOP. Now I&#8217;m not the sharpest pencil in the pack, but I know to listen when my unconscience &#8220;speaks&#8221;.</p>
<p>So I set about going over what I knew about AOP &#8211; interceptors, advisors, advice, introductions, etc, etc. And then it dawned on me. I could intercept all calls to any object that implemented IView, check the parameters of those calls, and if they implemented IEntity, to clone them before passing them through.</p>
<p>&lt;Homer-style WOOHOO /&gt;</p>
<p>The great thing is that developers don&#8217;t need to remember to clone entities &#8211; it happens automatically. The even greater thing is that this will lead developers to writing the correct kind of interaction between their views and supervising controllers.</p>
<p>Together with <a href="http://www.nServiceBus.com">nServiceBus</a>, this is going to make the extremely difficult problem of writing thread-safe smart clients possible. </p>
<p>I&#8217;ve never made use of AOP in a framework before so I&#8217;d like to get the broader community&#8217;s feedback on this before incorporating this in production. I&#8217;ve spoken with some serious AOP folks who have allayed most of my uncertainties, but I&#8217;d like to hear more. Anyway, here&#8217;s the <a href="http://udidahan.weblogs.us/wp-content/uploads/aoptest.zip">proof of concept</a> (that makes use of <a href="http://www.springframework.net">Spring</a>). </p>
<p>If this turns out to be a viable solution, I think we&#8217;ll have a solid environment for building a software factory on top of. That is something that I&#8217;m really excited about. In this multi-core future (present) that is upon us, multi-threading on the client is pretty much a necessity. We need a way to get things safe and stable by default without requiring a member of the CLR team to hold our hand.</p>
<p>Anybody who&#8217;s interested in helping, drop a comment below.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2007/12/07/eureka-aop-is-the-final-piece-of-the-multi-threaded-smart-client-puzzle/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Asynchronous, High-Performance Login for Web Farms</title>
		<link>http://www.udidahan.com/2007/11/10/asynchronous-high-performance-login-for-web-farms/</link>
		<comments>http://www.udidahan.com/2007/11/10/asynchronous-high-performance-login-for-web-farms/#comments</comments>
		<pubDate>Sat, 10 Nov 2007 16:08:46 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Autonomous Services]]></category>
		<category><![CDATA[Availability]]></category>
		<category><![CDATA[Caching]]></category>
		<category><![CDATA[Data Access]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[ESB]]></category>
		<category><![CDATA[NServiceBus]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[Workflow]]></category>

		<guid isPermaLink="false">http://udidahan.weblogs.us/2007/11/10/asynchronous-high-performance-login-for-web-farms/</guid>
		<description><![CDATA[Often during my consulting engagements I run into people who say, &#34;some things just can&#8217;t be made asynchronous&#34; even after they agree about the inherent scalability that asynchronous communications pattern bring. One often-cited example is user authentication &#8211; taking a username and password combo and authenticating it against some back-end store. For the purpose of [...]]]></description>
			<content:encoded><![CDATA[<p>Often during my consulting engagements I run into people who say, &quot;some things just can&#8217;t be made asynchronous&quot; even after they agree about the inherent scalability that asynchronous communications pattern bring. One often-cited example is user authentication &#8211; taking a username and password combo and authenticating it against some back-end store. For the purpose of this post, I&#8217;m going to assume a database. Also, I&#8217;m not going to be showing more advanced features like ETags to further improve the solution.</p>
<h3>The Setup</h3>
<p>Just so that the example is in itself secure, we&#8217;ll assume that the password is one-way hashed before being stored. Also, given a reasonable network infrastructure our web servers will be isolated in the <a href="http://en.wikipedia.org/wiki/Demilitarized_zone_(computing)">DMZ</a> and will have to access some application server which, in turn, will communicate with the DB. There&#8217;s also a good chance for something like round-robin load-balancing between web servers, especially for things like user login.</p>
<p>Before diving into the meat of it, I wanted to preface with a few words. One of the commonalities I&#8217;ve found when people dismiss asynchrony is that they don&#8217;t consider a real deployment environment, or scaling up a solution to multiple servers, farms, or datacenters.</p>
<h3>The Synchronous Solution</h3>
<p>In the synchronous solution, each one of our web servers will be contacting the app server for each user login request. In other words, the load on the app server and, consequently, on the database server will be proportional to the number of logins. One property of this load is its data locality, or rather, the lack of it. Given that user U logged in, the DB won&#8217;t necessarily gain any performance benefits by loading all username/password data into memory for the same page as user U. Another property is that this data is very non-volatile &#8211; it doesn&#8217;t change that often.</p>
<p>I won&#8217;t go to far into the synchronous solution since its been <a href="http://www.michaelnygard.com/blog/2007/11/two_ways_to_boost_your_flaggin.html">analysed</a> numerous times before. The bottom line is that the database is the bottleneck. You could use sharding solutions. Many of the large sites have numerous read-only databases for this kind of data, with one master for updates &#8211; replicating out to the read-only replicas. That&#8217;s <a href="http://www.michaelnygard.com/blog/2007/11/two_quick_observations.html">great</a> if you&#8217;re using a nice cheap database like mySql (of LAMP), not so nice if you&#8217;re running Oracle or MS Sql Server.</p>
<p>Regardless of what you&#8217;re doing in your data tier, you&#8217;re there. Wouldn&#8217;t it be nice to close the loop in the web servers? Even if you are using Apache, that&#8217;s going to be less iron, electricity, and cooling all around. That&#8217;s what the asynchronous solution is all about &#8211; capitalizing on the low cost of memory to save on other things.</p>
<h3>The Asynchronous Solution</h3>
<p>In the asynchronous solution, we cache username/hashed-password pairs in memory on our web servers, and authenticate against that. Let&#8217;s analyse how much memory that takes:</p>
<p>Usernames are usually 12 characters or less, but let&#8217;s take an average of 32 to be sure. Using Unicode we get to 64 bytes for the username. Hashed passwords can run between 256 and 512 <em>bits</em> depending on the algorithm, divide by 8 and you have 64 bytes. That&#8217;s about 128 bytes altogether. So we can safely cache 8 million of these with 1GB of memory per web server. If you&#8217;ve got a million users, first of all, good for you <img src='http://www.udidahan.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Second, that&#8217;s just 128 MB of memory &#8211; relatively nothing even for a cheap 2GB web server. </p>
<p>Also, consider the fact that when registering a new user we can check if such a username is already taken at the web server level. That doesn&#8217;t mean it won&#8217;t be checked again in the DB to account for <a href="http://udidahan.weblogs.us/2007/01/22/realistic-concurrency/">concurrency issues</a>, but that the load on the DB is further reduced. Other things to notice include no read-only replicas and no replication. Simple. Our web servers are the &quot;replicas&quot;.</p>
<h3>The Authentication Service</h3>
<p>What makes it all work is the &quot;Authentication Service&quot; on the app server. This was always there in the synchronous solution. It is what used to field all the login requests from the web servers, and, of course, allowed them to register new users and all the regular stuff. The difference is that now it publishes a message when a new user is registered (or rather, is validated &#8211; all a part of the internal long-running workflow). It also allows subscribers to receive the list of all username/hashed-password pairs. It&#8217;s also quite likely that it would keep the same data in memory too.</p>
<p>The same message can be used to publish both single updates, and returning the full list when using <a href="http://www.NServiceBus.com">NServiceBus</a>. Let&#8217;s define the message:</p>
<div style="border-right: black 1px solid; padding-right: 1em; border-top: black 1px solid; padding-left: 1em; padding-bottom: 0em; overflow: auto; border-left: black 1px solid; padding-top: 0em; border-bottom: black 1px solid; font-family: courier; background-color: beige">
<p>[Serializable]      <br />public class UsernameInUseMessage : IMessage       <br />{       <br />&#160;&#160;&#160; private string username;       <br />&#160;&#160;&#160; public string Username       <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; get { return username; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; set { username = value; }       <br />&#160;&#160;&#160; } </p>
</p>
<p>&#160;&#160;&#160; private byte[] hashedPassword;      <br />&#160;&#160;&#160; public byte[] HashedPassword       <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; get { return hashedPassword; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; set { hashedPassword = value; }       <br />&#160;&#160;&#160; }       <br />} </p>
</p></div>
<p>And the message that the web server sends when it wants the full list:</p>
</p>
<div style="border-right: black 1px solid; padding-right: 1em; border-top: black 1px solid; padding-left: 1em; padding-bottom: 0em; overflow: auto; border-left: black 1px solid; padding-top: 0em; border-bottom: black 1px solid; font-family: courier; background-color: beige">
<p>[Serializable]      <br />public class GetAllUsernamesMessage : IMessage       <br />{ </p>
<p>} </p>
</p></div>
<p>And the code that the web server runs on startup looks like this (assuming constructor injection):</p>
<p>&#160;</p>
</p>
<div style="border-right: black 1px solid; padding-right: 1em; border-top: black 1px solid; padding-left: 1em; padding-bottom: 0em; overflow: auto; border-left: black 1px solid; padding-top: 0em; border-bottom: black 1px solid; font-family: courier; background-color: beige">
<p>public class UserAuthenticationServiceAgent      <br />{&#160; <br />&#160;&#160;&#160; public UserAuthenticationServiceAgent(IBus bus)&#160; <br />&#160;&#160;&#160; {&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.bus = bus;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; bus.Subscribe(typeof(UsernameInUseMessage));&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; bus.Send(new GetAllUsernamesMessages());       <br />&#160;&#160;&#160; } </p>
<p> }</p></div>
<p>And the code that runs in the Authentication Service when the GetAllUsernamesMessage is received:</p>
</p>
<p>&#160;</p>
</p>
<div style="border-right: black 1px solid; padding-right: 1em; border-top: black 1px solid; padding-left: 1em; padding-bottom: 0em; overflow: auto; border-left: black 1px solid; padding-top: 0em; border-bottom: black 1px solid; font-family: courier; background-color: beige">
<p>public class GetAllUsernamesMessageHandler : BaseMessageHandler&lt;GetAllUsernamesMessage&gt;      <br />{       <br />&#160;&#160;&#160; public override void Handle(GetAllUsernamesMessage message)       <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.Bus.Reply(Cache.GetAll&lt;UsernameInUseMessage&gt;());       <br />&#160;&#160;&#160; }       <br />}</p>
</p></div>
<p>&#160;</p>
<p>And the class on the web server that handles a UsernameInUseMessage when it arrives:</p>
</p>
<p>&#160;</p>
</p>
<div style="border-right: black 1px solid; padding-right: 1em; border-top: black 1px solid; padding-left: 1em; padding-bottom: 0em; overflow: auto; border-left: black 1px solid; padding-top: 0em; border-bottom: black 1px solid; font-family: courier; background-color: beige">
<p>public class UsernameInUseMessageHandler : BaseMessageHandler&lt;UsernameInUseMessage&gt;      <br />{       <br />&#160;&#160;&#160; public override void Handle(UsernameInUseMessage message)       <br />&#160;&#160;&#160; {&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; WebCache.SaveOrUpdate(message.Username, message.HashedPassword);&#160; <br />&#160;&#160;&#160; }       <br />}</p>
</p></div>
<p>When the app server sends the full list, multiple objects of the type UsernameInUseMessage are sent in one physical message to that web server. However, the bus object that runs on the web server dispatches each of these logical messages one at a time to the message handler above.</p>
<p>So, when it comes time to actually authenticate a user, this the web page (or controller, if you&#8217;re doing MVC) would call:</p>
</p>
<div style="border-right: black 1px solid; padding-right: 1em; border-top: black 1px solid; padding-left: 1em; padding-bottom: 0em; overflow: auto; border-left: black 1px solid; padding-top: 0em; border-bottom: black 1px solid; font-family: courier; background-color: beige">
<p>public class UserAuthenticationServiceAgent      <br />{       <br />&#160;&#160;&#160; public bool Authenticate(string username, string password)       <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; byte[] existingHashedPassword = WebCache[username];       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (existingHashedPassword != null)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return existingHashedPassword == this.Hash(password); </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; return false;      <br />&#160;&#160;&#160; }       <br />}</p>
</p></div>
<p>&#160;</p>
<p>When registering a new user, the web server would of course first check its cache, and then send a RegisterUserMessage that contained the username and the hashed password.</p>
</p>
<div style="border-right: black 1px solid; padding-right: 1em; border-top: black 1px solid; padding-left: 1em; padding-bottom: 0em; overflow: auto; border-left: black 1px solid; padding-top: 0em; border-bottom: black 1px solid; font-family: courier; background-color: beige">
<p>[Serializable]      <br />[StartsWorkflow]       <br />public class RegisterUserMessage : IMessage       <br />{       <br />&#160;&#160;&#160; private string username;       <br />&#160;&#160;&#160; public string Username       <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; get { return username; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; set { username = value; }       <br />&#160;&#160;&#160; } </p>
</p>
<p>&#160;&#160;&#160; private string email;      <br />&#160;&#160;&#160; public string Email       <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; get { return email; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; set { email = value; }       <br />&#160;&#160;&#160; } </p>
</p>
<p>&#160;&#160;&#160; private byte[] hashedPassword;      <br />&#160;&#160;&#160; public byte[] HashedPassword       <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; get { return hashedPassword; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; set { hashedPassword = value; }       <br />&#160;&#160;&#160; }       <br />} </p>
</p></div>
<p>&#160;</p>
<p>When the RegisterUserMessage arrives at the app server, a new long-running workflow is kicked off to handle the process:</p>
</p>
<div style="border-right: black 1px solid; padding-right: 1em; border-top: black 1px solid; padding-left: 1em; padding-bottom: 0em; overflow: auto; border-left: black 1px solid; padding-top: 0em; border-bottom: black 1px solid; font-family: courier; background-color: beige">
<p>public class RegisterUserWorkflow :      <br />&#160;&#160;&#160; BaseWorkflow&lt;RegisterUserMessage&gt;, IMessageHandler&lt;UserValidatedMessage&gt;       <br />{       <br />&#160;&#160;&#160; public void Handle(RegisterUserMessage message)       <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; //send validation request to message.Email containing this.Id (a guid)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; // as a part of the URL       <br />&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160; /// &lt;summary&gt;      <br />&#160;&#160;&#160; /// When a user clicks the validation link in the email, the web server       <br />&#160;&#160;&#160; /// sends this message (containing the workflow Id)       <br />&#160;&#160;&#160; /// &lt;/summary&gt;       <br />&#160;&#160;&#160; /// &lt;param name=&quot;message&quot;&gt;&lt;/param&gt;       <br />&#160;&#160;&#160; public void Handle(UserValidatedMessage message)       <br />&#160;&#160;&#160; {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; // write user to the DB </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.Bus.Publish(new UsernameInUseMessage(      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; message.Username, message.HashedPassword));       <br />&#160;&#160;&#160; }       <br />}</p>
</p></div>
<p>That UsernameInUseMessage would eventually arrive at all the web servers subscribed.</p>
<h3>Performance/Security Trade-Offs</h3>
<p>When looking deeper into this workflow we realize that it could be implemented as two separate message handlers, and have the email address take the place of the workflow Id. The problem with this alternate, better performing solution has to do with security. By removing the dependence on the workflow Id, we&#8217;ve in essence stated that we&#8217;re willing to receive a UserValidatedMessage without having previously received the RegisterUserMessage. </p>
<p>Since the processing of the UserValidatedMessage is relatively expensive &#8211; writing to the DB and publishing messages to <em>all</em> web servers, a malicious user could perform a denial of service (<a href="http://en.wikipedia.org/wiki/Denial-of-service_attack">DOS</a>) attack without that many messages, thus flying under the radar of many detection systems. Spoofing a guid that would result in a valid workflow instance is much more difficult. Also, since workflow instances would probably be stored in some in-memory, replicated data grid the relative cost of a lookup would be quite small &#8211; small enough to avoid a DOS until a detection system picked it up.</p>
<h3>Improved Bandwidth &amp; Latency</h3>
<p>The bottom line is that you&#8217;re getting much more out of your web tier this way, rather than hammering your data tier and having to scale it out much sooner. Also, notice that there is much less network traffic this way. Not such a big deal for usernames and passwords, but other scenarios built in the same way may need more data. Of course, the time it takes us to log a user in is much shorter as well since we don&#8217;t have to cross back and forth from the web server (in the DMZ) to the app server, to the db server.</p>
<p>The important thing to remember in this solution is doing pub/sub. NServiceBus merely provides a simple API for designing the system around pub/sub. And publishing is where you get the serious scalability. As you get more users, you&#8217;ll obviously need to get more web servers. The thing is that you probably won&#8217;t need more database servers <em>just to handle logins</em>. In this case, you also get <a href="http://www.michaelnygard.com/blog/2007/11/architecting_for_latency.html">lower latency</a> per request since all work needed to be done can be done locally on the server that received the request. </p>
<h3>ETags make it even better</h3>
<p>For the more advanced crowd, I&#8217;ll wrap it up with the <a href="http://en.wikipedia.org/wiki/HTTP_ETag">ETags</a>. Since web servers do go down, and the cache will be cleared, what we can do is to write that cache to disk (probably in a background thread), and &quot;tag&quot; it with something that the server gave us along with the last UsernameInUseMessage we received. That way, when the web server comes back up, it can send that ETag along with its GetAllUsernamesMessage so that the app server will only send the changes that occurred since. This drives down network usage even more at the insignificant cost of some disk space on the web servers.</p>
<h3>And in closing&#8230;</h3>
<p>Even if you don&#8217;t have anything more than a single physical server today, and it acts as your web server and database server, this solution won&#8217;t slow things down. If anything, it&#8217;ll speed it up. Regardless, you&#8217;re much better prepared to scale out than before &#8211; no need to rip and replace your entire architecture just as you get 8 million Facebook users banging down your front door.</p>
<p>So, go check out <a href="http://www.NServiceBus.com">NServiceBus</a> and get the most out of your iron.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2007/11/10/asynchronous-high-performance-login-for-web-farms/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Hi. My name&#8217;s Udi, and I write crappy code</title>
		<link>http://www.udidahan.com/2007/10/30/hi-my-names-udi-and-i-write-crappy-code/</link>
		<comments>http://www.udidahan.com/2007/10/30/hi-my-names-udi-and-i-write-crappy-code/#comments</comments>
		<pubDate>Tue, 30 Oct 2007 11:21:01 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Management]]></category>

		<guid isPermaLink="false">http://udidahan.weblogs.us/2007/10/30/hi-my-names-udi-and-i-write-crappy-code/</guid>
		<description><![CDATA[&#8220;I am human, therefore I make mistakes. If I make mistakes, then I cannot assume that I will write code that has no mistakes. If I cannot write code that has no mistakes, then I must assume that mistakes are rampant within the code. If mistakes are rampant within the code, then I must find [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;I am human, therefore I make mistakes. If I make mistakes, then I cannot assume that I will write code that has no mistakes. If I cannot write code that has no mistakes, then I must assume that mistakes are rampant within the code. If mistakes are rampant within the code, then I must find them. But because I make mistakes, then I must also assume that I make mistakes trying to identify the mistakes in the code. <em>Therefore, I will seek the best support I can find in helping me find the mistakes in my code.</em>&#8221;</p>
<p>Source: <a href="http://blogs.tedneward.com/2007/10/30/Welcome+To+The+Shitty+Code+Support+Group.aspx">Ted Neward&#8217;s post: Welcome To The Shitty Code Support Group</a>.</p>
<p>And I consider myself to be a top 10% kind-of-guy.</p>
<p>Imagine the kind of crap all those other people are putting out. Not you, the reader, of course. The fact that you&#8217;re reading my writing means you&#8217;re a top 10% kind of person too <img src='http://www.udidahan.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
<p>Having good design helps.</p>
<p>Helps decrease the impact mistakes in one part of the system have on other parts.</p>
<p>That way, when I&#8217;m working on one part of the system, I only have to deal with my crap. And that&#8217;s a good thing. Because I&#8217;ve gotten pretty good at fixing my crap over the years.</p>
<p>&#8211;</p>
<p>This movement is definitely a good thing, over all. Moving to a failure-oriented mindset will help us put the appropriate tools and processes in place to making more robust systems, maybe even <a href="http://udidahan.weblogs.us/2007/08/24/make-non-stop-software-simple-make-it-possible/">Non-Stop Software</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2007/10/30/hi-my-names-udi-and-i-write-crappy-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ObjectBuilder synchronization features needed for pub/sub-ing Smart Clients</title>
		<link>http://www.udidahan.com/2007/09/28/objectbuilder-synchronization-features-needed-for-pubsub-ing-smart-clients/</link>
		<comments>http://www.udidahan.com/2007/09/28/objectbuilder-synchronization-features-needed-for-pubsub-ing-smart-clients/#comments</comments>
		<pubDate>Fri, 28 Sep 2007 21:36:58 +0000</pubDate>
		<dc:creator>thesoftwaresimplist</dc:creator>
				<category><![CDATA[Dependency Injection]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[Smart Client]]></category>
		<category><![CDATA[Threading]]></category>

		<guid isPermaLink="false">http://udidahan.weblogs.us/2007/09/28/objectbuilder-synchronization-features-needed-for-pubsub-ing-smart-clients/</guid>
		<description><![CDATA[I&#8217;ve been getting some questions from the Dependency Injection folks out there as to why I have my own Object Builder wrapping the framework. There are two very good reasons why I do this:
The first is to insulate the framework and application code that I write from the choice of one dependency injection technology or [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been getting some questions from the Dependency Injection folks out there as to why I have my own Object Builder wrapping the framework. There are two very good reasons why I do this:</p>
<p>The first is to insulate the framework and application code that I write from the choice of one dependency injection technology or another. I want the ability to switch easily from one to the other &#8211; not so much that projects go back and forth. Updating those config files is definitely <i>not</i> easy. However, it allows me to have &#8220;portable&#8221; framework code that is applicable to all the projects I consult on, regardless of their choice of technology.</p>
<p>The second has to do with <a href="http://udidahan.weblogs.us/category/nservicebus/">NServiceBus</a> specifically. In order to make use of duplex communication on smart clients, you need a background thread. That thread will be updating the same (model) objects as the UI thread. That means we need synchronization. I prefer to use .NET&#8217;s built-in synchronization domains in order to solve this rather thorny problem.</p>
<p>The only thing is that message handlers need to be in the synchronization domain so that they can easily update those objects. However, the Bus object must not be in the synchronization domain so that if we&#8217;ve received a large update from the server, we won&#8217;t be locking out the UI thread from interacting with data on the client. </p>
<p>Since the bus makes use of a dependency injection framework to create message handlers, this was the best place to put the code which causes message handlers to run within the synchronization domain.</p>
<p>Be aware that in order to enjoy this feature, you need to split up those large server updates into multiple, logical objects (that implement IMessage), but you can still publish them all in one go using the method: </p>
<p>void Publish(params IMessage[] messages);</p>
<p>And, of course, you need to set the JoinSynchronizationDomain property of the Object Builder.</p>
<p>I&#8217;ll have a podcast coming out on this topic soon.</p>
<p>You can get the code here:</p>
<p><a href='http://udidahan.weblogs.us/wp-content/uploads/objectbuilder.zip' title='Object Builder.zip'>Object Builder.zip</a></p>
<p>But you&#8217;ll have to get the Spring Framework code from the <a href="http://springframework.net/">official site</a>. Make sure you download <a href="http://sourceforge.net/project/showfiles.php?group_id=106751">RC 1.1</a>. Then, take the binaries and copy them to the &#8220;BIN&#8221; folder of the Object Builder solution. If you&#8217;re looking to save on some &#8220;weight&#8221;, you only need &#8220;Spring.Core.dll&#8221;, &#8220;Common.Logging.dll&#8221; and &#8220;antlr.runtime.dll&#8221; for the solution to compile. You will need one of the logging implementations DLLs to get anything written to a log, obviously.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2007/09/28/objectbuilder-synchronization-features-needed-for-pubsub-ing-smart-clients/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
