<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DUcBRXc6eip7ImA9WxBWEkU.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662</id><updated>2010-02-04T12:37:34.912Z</updated><title>Robust Software</title><subtitle type="html">Tales of a code samurai</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.robustsoftware.co.uk/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>48</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/RobustSoftware" /><feedburner:info uri="robustsoftware" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry gd:etag="W/&quot;DUcBRXc9fCp7ImA9WxBWEkU.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-4281230491931014918</id><published>2010-02-04T12:37:00.001Z</published><updated>2010-02-04T12:37:34.964Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-04T12:37:34.964Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Open Rasta" /><category scheme="http://www.blogger.com/atom/ns#" term="REST" /><category scheme="http://www.blogger.com/atom/ns#" term="Architecture" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC" /><category scheme="http://www.blogger.com/atom/ns#" term="Rails" /><title>Questioning commonly held opinions</title><content type="html">&lt;p&gt;I’ve been looking into rails recently, partly to learn rails itself, partly to try and gain inspiration for the direction to take both the framework we use at work and Jamaica. It’s triggered me to question a lot of things that I’m doing in .NET so I’m going to attempt to record my thoughts.&lt;/p&gt;  &lt;h3&gt;Having testing and persistence baked in&lt;/h3&gt;  &lt;p&gt;One thing that has struck me is that I’m watching railscasts from years ago and they are demonstrating solutions to problems ASP.NET MVC is struggling with now. It really does have testing baked in but often not through the use of abstractions, instead they have made integration tests easy to write. It appears the entire request can be processed in memory without having to fire up a server all the way through to rendering the view. This is something OpenRasta is capable of and one of the reasons I get so excited about it.&lt;/p&gt;  &lt;p&gt;Another benefit rails has is that it comes with a “model” baked in. This is something that is sorely lacking from ASP.NET MVC. Whereas the .NET world (particularly the ALT.NET sphere) favours NHibernate for persistence, they instead use a simple but well implemented active record implementation. Why have they chosen this? Partially because it works so well with a dynamic language, everything is DRY as code can be generated from the database at runtime. It’s also damn quick, something that has always bugged me about NHibernate is the 10-20 seconds it takes to create the session factory before you can get started. &lt;/p&gt;  &lt;p&gt;Because NHibernate is so powerful and configurable it can quite frankly be bloody confusing for most developers, I get asked to help with problems almost daily. With active record everything is kept simple, this object is a row in that table. There aren’t often complex mapping files, it just works. Rails’ active record implementation has a layer of syntactic sugar based around pattern matching on missing methods which looks nice and works well. However, in .NET we have LINQ which is statically typed, very powerful and can serve the same purpose. &lt;/p&gt;  &lt;h3&gt;Why do we chose NHibernate? &lt;/h3&gt;  &lt;p&gt;The reasons given for choosing NHibernate are persistence ignorance, reducing the impedance mismatch, amongst others. Why do we insist on ignoring the fact that our applications are running on top of a relational database? What ever happened to embracing the technologies we are using to get the best out of them? &lt;/p&gt;  &lt;p&gt;NHibernate lets you persist your domain models directly. So what? Who’s domain models are that much beyond dumb data stores in reality? I’d bargain it’s a hell of a lot less than those that claim to be doing domain driven design. Also, why does your domain have to be persisted directly? Why couldn’t you provide an empty domain object with a few active record objects and have it process them and spit other active record objects out the other side? Something CQRS-ish. Then your domain would contain nothing but business logic.&lt;/p&gt;  &lt;h3&gt;What does this mean? &lt;/h3&gt;  &lt;p&gt;I’m looking away from NHibernate, no tool should be chosen without question, even the great NHibernate. I just don’t think it is serving my needs as well as it could so I’m going to look for alternatives. Subsonic is top of my list, followed by revisiting LINQ to SQL, hell I might even take a look at the Entity Framework.&lt;/p&gt;  &lt;p&gt;While we’re at it, why do we chose relational databases without question? I’ve been working with Lucene.NET a lot recently, it’s really easy to use and you get full-text indexing for free if you were to use it as a data store. Only want to deal with aggregate roots? Store all the data of that aggregate root in a single document, it can easily emulate nested structures.&lt;/p&gt;  &lt;h3&gt;Random deviation onto REST&lt;/h3&gt;  &lt;p&gt;I’m also being influenced by how REST appeals to me. It seems like a simple yet powerful way of dealing with the web. If we consider everything we work with as a resource, a representation of an idea, why can’t that representation be stored as an active record? The transition of an idea between resources could actually be a record transferring between tables. The old representation could even hold a reference to what the idea became, allowing you to redirect to the current representation. Hell, wasn’t the web made for storing and linking documents before it got bastardised into the beautiful beast we have today? Perhaps a document database would be ideally suited!&lt;/p&gt;  &lt;h3&gt;Pain points of ASP.NET MVC&lt;/h3&gt;  &lt;p&gt;Talking of REST brings me back to another problem I have with ASP.NET MVC. The routing revolves around controllers and actions rather than the resources and HTTP methods. In order to generate URIs, you will at some point end up having to manipulate strings or create anonymous objects. How do rails and OpenRasta deal with this? By using resources and their types to determine the URIs. This is so much more powerful and dare I say easier to use and understand. I can see it empowering the use of generics within .NET and it cuts out a hell of a lot of crap around URI generation.&lt;/p&gt;  &lt;p&gt;Ah, cutting out the crap. ASP.NET MVC is testable, until you want to test something that isn’t a just a controller action. Like a HTML helper, URI generation or store the IP address of the request. Most of these things are kind of testable, but you have to mock out a complex object graph like HttpContextBase or ControllerContext. “We got rid of HttpContext.Current and replaced it with something slightly less monolithic and slight less sealed, go us!”. Know how OpenRasta deals with this? It has dependency injection at it’s core and there’s an interface that lets you retrieve everything you need, either separately or together. There’s everything from IRequest to ICommunicationContext (the equivalent of ControllerContext) and everything in between. You need it, you can retrieve it and it’s bloody easy to test.&lt;/p&gt;  &lt;h3&gt;Wrapping up&lt;/h3&gt;  &lt;p&gt;There’s a lot of random ideas here, I can’t say which I’ll end up using. Perhaps none of them, perhaps an unforeseen combination. If nothing else writing this down has helped me distil a few of them into clearer thoughts.&lt;/p&gt;  &lt;p&gt;Here’s to questioning everything you believe to be true.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-4281230491931014918?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=-EiejxZM5Uk:rHU4wArHihE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=-EiejxZM5Uk:rHU4wArHihE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=-EiejxZM5Uk:rHU4wArHihE:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=-EiejxZM5Uk:rHU4wArHihE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=-EiejxZM5Uk:rHU4wArHihE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=-EiejxZM5Uk:rHU4wArHihE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=-EiejxZM5Uk:rHU4wArHihE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/-EiejxZM5Uk" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/4281230491931014918?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/4281230491931014918?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/-EiejxZM5Uk/questioning-commonly-held-opinions.html" title="Questioning commonly held opinions" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/09896269341967717523</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="17836723317508089121" /></author><feedburner:origLink>http://blog.robustsoftware.co.uk/2010/02/questioning-commonly-held-opinions.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUAFRns-eyp7ImA9WxBXFE4.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-8499385263067200694</id><published>2010-01-25T15:35:00.001Z</published><updated>2010-01-25T15:35:17.553Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-25T15:35:17.553Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="BDD" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="Quality" /><title>Test-Driven Development – 3 Years On</title><content type="html">&lt;p&gt;I’ve been questioning my own practices recently, seeing if there were places that I could improve, both in quality and productivity. Part of this process involved an evaluation of my test-driven approach (TDD) to developing software.&lt;/p&gt;  &lt;p&gt;I have gained and learnt so much by practicing TDD. I believe there is no better way to instil the SOLID principle within both yourself and your code than to practice TDD. Violate any of the principles and you feel the pain in your tests, they will either become monolithic and hard to write or continuously break.&lt;/p&gt;  &lt;p&gt;Here lies the chicken and the egg situation: to write good, robust tests you have to understand SOLID; to understand SOLID you have to be testing your code. This creates quite a hurdle that many people don’t put forth the effort to overcome. This is a shame but I think an excellent way of splitting the wheat from the chaff. In order to become proficient at testing you either need to have a natural talent for writing good code or the persistence to break through to the required level of understanding. Both of these qualities are equally valuable, having both would be fantastic.&lt;/p&gt;  &lt;p&gt;The quality of code produced by TDD has never been in doubt in my mind. What I am questioning is the return-on-investment (ROI) of each test I write. Sometimes I feel I am writing a test for the sake of writing a test, producing very little value in the process. The kind of scenario where this is most apparent is the sort of code where if you were to not have written it properly nothing would happen or it would blow up in your face. Code with real binary levels of success, often with a single path through it.&lt;/p&gt;  &lt;p&gt;This is the elephant in the room of all TDD discussions. When am I testing too much? The standard response of “NEVER!” is a lie but you have to have practiced TDD for a decent while until you can judge when you’re going to be writing tests with little worth. I’ve identified a subset of tests that I’m probably wasting my time in writing which are clouding the overall message of my test suite. The problem is that I am responsible for mentoring several developers in how and when to craft tests. I have to lead by example and until the whole team reaches a higher level of understanding of TDD I have to test everything despite knowing some of the tests I write have little to no value.&lt;/p&gt;  &lt;p&gt;How can I test everything without writing these low value tests? Currently I’m looking at integration acceptance tests that describe the behaviour of the system. These will verify that the several layers of the application interact as expected in given scenarios to produce the desired behaviour of the system. These will likely have meaty setups and meaty verifications but they will remove the need for multiple low ROI tests. They are likely to be more brittle than unit tests but so long as I verify outcomes rather than interactions they should be fairly robust. What I’d love to experiment with is getting the stakeholders to help me write these acceptance tests, but this will have to wait until I’ve settled on a style for writing them. There’s nothing that harms adoption of a practice more than the first interaction to be a bumbling mess as you are not sure of what you’re doing!&lt;/p&gt;  &lt;p&gt;As a company, we are also looking to hire testers this year. This is another thing stopping me from cutting out the low ROI tests. If I do not test my code, it will not get tested through anything but a manual process. Once we have testers I may be able to just write the tests that drive the behaviour and design of my code, leaving the full suite of tests to be developed by the testers.&lt;/p&gt;  &lt;p&gt;So what have I learnt over the past few years? Is test-driven development worth the effort? Most definitely. The quality of my code has come on leaps and bounds and each time you do a major refactor of a well tested code base is a revelation. I find I write less code to do more and writing less code is always a good thing. &lt;/p&gt;  &lt;p&gt;It’s harder to be sure you spend less time fixing bugs if I’m honest but I’m confident it’s the case. If you’re just starting out with TDD or unit testing in any form, start tracking the hours spent developing versus bug fixing. It would be interesting to see some empirical values on the subject.&lt;/p&gt;  &lt;p&gt;Here’s to future years of TDD. It’s going to be interesting to see where my practices go.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-8499385263067200694?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=uZqa2wPaPOo:g2Ik0Vlxz_I:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=uZqa2wPaPOo:g2Ik0Vlxz_I:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=uZqa2wPaPOo:g2Ik0Vlxz_I:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=uZqa2wPaPOo:g2Ik0Vlxz_I:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=uZqa2wPaPOo:g2Ik0Vlxz_I:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=uZqa2wPaPOo:g2Ik0Vlxz_I:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=uZqa2wPaPOo:g2Ik0Vlxz_I:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/uZqa2wPaPOo" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/8499385263067200694?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/8499385263067200694?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/uZqa2wPaPOo/test-driven-development-3-years-on.html" title="Test-Driven Development – 3 Years On" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/09896269341967717523</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="17836723317508089121" /></author><feedburner:origLink>http://blog.robustsoftware.co.uk/2010/01/test-driven-development-3-years-on.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0EDRH47fCp7ImA9WxBTGU0.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-6890763988644147583</id><published>2009-12-15T19:34:00.001Z</published><updated>2009-12-15T19:34:35.004Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-15T19:34:35.004Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Open Rasta" /><title>A better ActionResult: Open Rasta edition (part 2)</title><content type="html">&lt;p&gt;&lt;a href="http://serialseb.blogspot.com/" target="_blank"&gt;Sebastien Lambla&lt;/a&gt;, who created &lt;a href="http://www.openrasta.com" target="_blank"&gt;Open Rasta&lt;/a&gt;, mentioned that I could use an operation interceptor rather than using a pipeline contributor as in &lt;a href="http://blog.robustsoftware.co.uk/2009/12/better-actionresult-open-rasta-edition.html" target="_blank"&gt;the first “A better ActionResult” post&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;I must admit that I didn’t know about operation interceptors which is the main reason I didn’t use one in the first post. I took this as an opportunity to learn a bit more about &lt;a href="http://www.openrasta.com" target="_blank"&gt;Open Rasta&lt;/a&gt; and so looked into what operation interceptors are and how to create them.&lt;/p&gt;  &lt;p&gt;Creating an operation interceptor is an unsurprisingly simple task. You can either implement the interface IOperationInterceptor or inherit from OperationInterceptor which implements IOperationInterceptor with virtual methods that have no effect on the operation. &lt;/p&gt;  &lt;p&gt;The latter is the easiest thing to do so that’s what how we’re going to implement our interceptor.&lt;/p&gt;  &lt;p&gt;The IOperationInterceptor has 3 methods: BeforeExecute, RewriteOperation and AfterExecute. We want to work with the result of the operation so we’ll override AfterExecute. The way the interceptor works once invoked is virtually identical to the pipeline contributor, bar a little refactoring, as you can see:&lt;/p&gt;  &lt;div style="padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.5em"&gt;   &lt;p style="line-height: 1.2em; margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;CommandOperationResultInterceptor&lt;/span&gt; : &lt;span style="color: #ffc66d"&gt;OperationInterceptor&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;readonly&lt;/span&gt; &lt;span style="color: #6897bb"&gt;IDependencyResolver&lt;/span&gt; resolver;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; CommandOperationResultInterceptor(&lt;span style="color: #6897bb"&gt;IDependencyResolver&lt;/span&gt; resolver)&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;this&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.resolver = resolver;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="color: #cc7832"&gt;bool&lt;/span&gt; AfterExecute(&lt;span style="color: #6897bb"&gt;IOperation&lt;/span&gt; operation, &lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #6897bb"&gt;IEnumerable&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;OutputMember&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt; outputMembers)&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; outputMember = outputMembers.FirstOrDefault();&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;if&lt;/span&gt; (outputMember == &lt;span style="color: #cc7832"&gt;null&lt;/span&gt;) &lt;span style="color: #cc7832"&gt;return&lt;/span&gt; &lt;span style="color: #cc7832"&gt;true&lt;/span&gt;;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; command = outputMember.Value &lt;span style="color: #cc7832"&gt;as&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;CommandOperationResult&lt;/span&gt;;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;if&lt;/span&gt; (command == &lt;span style="color: #cc7832"&gt;null&lt;/span&gt;) &lt;span style="color: #cc7832"&gt;return&lt;/span&gt; &lt;span style="color: #cc7832"&gt;true&lt;/span&gt;;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; outputMember.Value = ProcessCommand(command);&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;return&lt;/span&gt; &lt;span style="color: #cc7832"&gt;true&lt;/span&gt;;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;object&lt;/span&gt; ProcessCommand(&lt;span style="color: #ffc66d"&gt;CommandOperationResult&lt;/span&gt; command)&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; resolver.AddDependencyInstance(command.GetType(),&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; command, &lt;span style="color: #6897bb"&gt;DependencyLifetime&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.PerRequest);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; commandHandlerType = &lt;span style="color: #cc7832"&gt;typeof&lt;/span&gt;(&lt;span style="color: #ffc66d"&gt;CommandOperationResultHandler&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;&amp;gt;)&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .MakeGenericType(command.GetType());&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; commandHandler = (&lt;span style="color: #6897bb"&gt;ICommandOperationResultHandler&lt;/span&gt;)&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; resolver.Resolve(commandHandlerType);&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;return&lt;/span&gt; commandHandler.Execute();&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This is a direct replacement for the pipeline contributor. It uses the exact same commands and command handlers as the pipeline contributor so the only other difference is that we have to register the operation interceptor rather than the pipeline contributor:&lt;/p&gt;  &lt;div style="padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.5em"&gt;   &lt;p style="line-height: 1.2em; margin: 0px"&gt;&lt;span style="color: #ffc66d"&gt;ResourceSpace&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Uses.CustomDependency&amp;lt;&lt;/span&gt;&lt;span style="color: #6897bb"&gt;IOperationInterceptor&lt;/span&gt;, &lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;CommandOperationResultInterceptor&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;(&lt;/span&gt;&lt;span style="color: #6897bb"&gt;DependencyLifetime&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Transient);&lt;/span&gt;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;That’s all there is to it. Really simple given we had the code for the pipeline contributor already.&lt;/p&gt;  &lt;p&gt;The only difference between the pipeline contributor and the operation interceptor is that rather than dealing with a single operation result there could be multiple output members. From what I can gather there is only ever one output member which is the assumption I’ve embedded in the interceptor but I may be mistaken.&lt;/p&gt;  &lt;p&gt;Reflecting on the two approaches, I don’t think there’s much to chose between the two. I prefer the original method of using a pipeline contributor. It is more visible via the debug output of the pipeline and it is easier to retrieve the operation result at that point. However, knowing that operation interceptors exist and how to use them is beneficial. Another weapon in my &lt;a href="http://www.openrasta.com" target="_blank"&gt;Open Rasta&lt;/a&gt; armoury.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-6890763988644147583?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=tTJt0a4U6as:TVuTjfdOOmY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=tTJt0a4U6as:TVuTjfdOOmY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=tTJt0a4U6as:TVuTjfdOOmY:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=tTJt0a4U6as:TVuTjfdOOmY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=tTJt0a4U6as:TVuTjfdOOmY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=tTJt0a4U6as:TVuTjfdOOmY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=tTJt0a4U6as:TVuTjfdOOmY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/tTJt0a4U6as" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/6890763988644147583?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/6890763988644147583?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/tTJt0a4U6as/better-actionresult-open-rasta-edition_15.html" title="A better ActionResult: Open Rasta edition (part 2)" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/09896269341967717523</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="17836723317508089121" /></author><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/12/better-actionresult-open-rasta-edition_15.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0INQn08fip7ImA9WxBTGEw.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-4575421957199331168</id><published>2009-12-14T19:39:00.001Z</published><updated>2009-12-14T19:39:53.376Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-14T19:39:53.376Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Open Rasta" /><title>A better ActionResult: Open Rasta edition</title><content type="html">&lt;p&gt;I’ve been meaning to blog more about my experiences with &lt;a href="http://www.openrasta.com" target="_blank"&gt;Open Rasta&lt;/a&gt; but haven’t had a sufficiently focused topic to work with so far. However, whilst reading &lt;a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/12/12/enabling-ioc-in-asp-net-actionresults-or-a-better-actionresult.aspx" target="_blank"&gt;Jimmy Bogard’s post on a better ActionResult&lt;/a&gt; I thought doing similar would be equally possible with &lt;a href="http://www.openrasta.com" target="_blank"&gt;Open Rasta&lt;/a&gt;. Go off and read Jimmy’s post if you haven’t already because I’m going to assume you have.&lt;/p&gt;  &lt;p&gt;First, some things to know about &lt;a href="http://www.openrasta.com" target="_blank"&gt;Open Rasta&lt;/a&gt;. It handles requests by passing them through a pipeline. Now this isn’t some mythical process that you have to spend hours working out as with MVC. It is instead made up of pipeline contributors which you register as part of your configuration. To help you debug &lt;a href="http://www.openrasta.com" target="_blank"&gt;Open Rasta&lt;/a&gt; prints out all the contributors in the order they’ll be executed for you during initialisation. Another difference in &lt;a href="http://www.openrasta.com" target="_blank"&gt;Open Rasta&lt;/a&gt; is what things are called, controllers are handlers, actions are operations, action results are operation results and models are resources. Their function is similar enough to require no further explanation in the context of this post.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.openrasta.com" target="_blank"&gt;Open Rasta&lt;/a&gt; gives you about 15 contributors to form the basis of request handling which you can replace or add to as you see fit. What we will do in order to emulate Jimmy’s code is create a new contributor and insert it into the pipeline. These are pretty simple to create and register, here’s all the code for our custom pipeline contributor:&lt;/p&gt;  &lt;div style="padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.5em"&gt;   &lt;p style="line-height: 1.2em; margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;CommandOperationResultInvokerContributor&lt;/span&gt; : &lt;span style="color: #6897bb"&gt;IPipelineContributor&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;readonly&lt;/span&gt; &lt;span style="color: #6897bb"&gt;IDependencyResolver&lt;/span&gt; resolver;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; CommandOperationResultInvokerContributor(&lt;span style="color: #6897bb"&gt;IDependencyResolver&lt;/span&gt; resolver)&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;this&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.resolver = resolver;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; Initialize(&lt;span style="color: #6897bb"&gt;IPipeline&lt;/span&gt; pipelineRunner)&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pipelineRunner.Notify(ExecuteCommand)&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .After&amp;lt;&lt;span style="color: #ffc66d"&gt;KnownStages&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.&lt;/span&gt;&lt;span style="color: #6897bb"&gt;IOperationExecution&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;()&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .And.Before&amp;lt;&lt;span style="color: #ffc66d"&gt;KnownStages&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.&lt;/span&gt;&lt;span style="color: #6897bb"&gt;IOperationResultInvocation&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;();&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #6897bb"&gt;PipelineContinuation&lt;/span&gt; ExecuteCommand(&lt;span style="color: #6897bb"&gt;ICommunicationContext&lt;/span&gt; context)&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;if&lt;/span&gt; (!(context.OperationResult &lt;span style="color: #cc7832"&gt;is&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;CommandOperationResult&lt;/span&gt;))&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;return&lt;/span&gt; &lt;span style="color: #6897bb"&gt;PipelineContinuation&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Continue;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; commandOperationResultType = context.OperationResult.GetType();&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; resolver.AddDependencyInstance(commandOperationResultType, &lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; context.OperationResult, &lt;span style="color: #6897bb"&gt;DependencyLifetime&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.PerRequest);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; commandHandlerType = &lt;span style="color: #cc7832"&gt;typeof&lt;/span&gt;(&lt;span style="color: #ffc66d"&gt;CommandOperationResultHandler&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;&amp;gt;)&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .MakeGenericType(commandOperationResultType);&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; commandHandler = (&lt;span style="color: #6897bb"&gt;ICommandOperationResultHandler&lt;/span&gt;) &lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; resolver.Resolve(commandHandlerType);&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; context.OperationResult = commandHandler.Execute();&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;return&lt;/span&gt; &lt;span style="color: #6897bb"&gt;PipelineContinuation&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Continue;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;The Initialize method is called during initialisation so that &lt;a href="http://www.openrasta.com" target="_blank"&gt;Open Rasta&lt;/a&gt; can determine where in the pipeline you want your contributor to be invoked. The KnownStages class contains a bunch of interface aliases for significant stages in the standard pipeline allowing you to latch onto them without tying you to an implementation.&lt;/p&gt;  &lt;p&gt;KnownStages.IOperationExecution is the &lt;a href="http://www.openrasta.com" target="_blank"&gt;Open Rasta&lt;/a&gt; equivalent of invoking the controller action and KnownStages.IOperationResultInvocation is the the equivalent of executing the ActionResult produced by the action. We’re slipping in between these two steps so we can execute our command handlers when needed; allowing us to change the OperationResult before it is executed.&lt;/p&gt;  &lt;p&gt;So what do we actually do when this pipeline contributor gets invoked?&lt;/p&gt;  &lt;p&gt;First we check if the OperationResult attached to the ICommunicationContext is of the CommandOperationResult type. This is identical to checking whether the ActionResult is of the BetterActionResult type in Jimmy’s post. If it isn’t we exit our pipeline contributor, telling &lt;a href="http://www.openrasta.com" target="_blank"&gt;Open Rasta&lt;/a&gt; to carry on to the next stage in the pipeline.&lt;/p&gt;  &lt;div style="padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.5em"&gt;   &lt;p style="line-height: 1.2em; margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;abstract&lt;/span&gt; &lt;span style="color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;CommandOperationResult&lt;/span&gt; : &lt;span style="color: #ffc66d"&gt;OperationResult&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;If it is a CommandOperationResult we retrieve the type of the current OperationResult and use it to register the OperationResult with our dependency resolver for the lifetime of the current request. The reason we do this is to be able to take the OperationResult as a dependency of the command handler. I’m not sure if this is any better but it does avoid using reflection to execute the command handler.&lt;/p&gt;  &lt;p&gt;As a side note, &lt;a href="http://www.openrasta.com" target="_blank"&gt;Open Rasta&lt;/a&gt; uses an IDependencyResolver interface which is used throughout the codebase. It ships with it’s own implementation; I know there’s an implementation for Ninject and I think there’s one for StructureMap knocking around somewhere. I’ve only used the internal implementation as it does everything I’ve needed so far.&lt;/p&gt;  &lt;p&gt;We then work out the type of CommandOperationResultHandler we’ll need to handle this command and use it to retrieve an instance from the dependency resolver. Again, this is very similar to Jimmy’s code apart from the fact that we cast the result as an ICommandOperationResultHandler. This is the second of the things that lets us avoid reflection.&lt;/p&gt;  &lt;div style="padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.5em"&gt;   &lt;p style="line-height: 1.2em; margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;interface&lt;/span&gt; &lt;span style="color: #6897bb"&gt;ICommandOperationResultHandler&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;OperationResult&lt;/span&gt; Execute();&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;}&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;abstract&lt;/span&gt; &lt;span style="color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;CommandOperationResultHandler&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;T&amp;gt; &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; : &lt;span style="color: #6897bb"&gt;ICommandOperationResultHandler&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="color: #cc7832"&gt;readonly&lt;/span&gt; T command;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;protected&lt;/span&gt; CommandOperationResultHandler(T command)&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;this&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.command = command;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;abstract&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;OperationResult&lt;/span&gt; Execute();&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;We execute the command handler, which will have taken the CommandOperationResult as a dependency due to us registering it earlier. It could also take the ICommunicationContext as a dependency as &lt;a href="http://www.openrasta.com" target="_blank"&gt;Open Rasta&lt;/a&gt; registers that for you, as it does for IRequest, IResponse and the other things that make up ICommunicationContext. &lt;/p&gt;  &lt;p&gt;The result of executing the command handler is set as the OperationResult of the current ICommunicationContext, this encourages you to swap out the CommandOperationResult for one of the standard OperationResult objects which will then get handled as normal by the next stage in the pipeline, KnownStages.IOperationResultInvocation.&lt;/p&gt;  &lt;p&gt;Here’s my equivalent of Jimmy’s DeleteRequestResult and DeleteRequestResultInvoker:&lt;/p&gt;  &lt;div style="padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.5em"&gt;   &lt;p style="line-height: 1.2em; margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;DeleteCommand&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;T&amp;gt; : &lt;/span&gt;&lt;span style="color: #ffc66d"&gt;CommandOperationResult&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; DeleteCommand(T resource)&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Resource = resource;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; T Resource { &lt;span style="color: #cc7832"&gt;get&lt;/span&gt;; &lt;span style="color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="color: #cc7832"&gt;set&lt;/span&gt;; }&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;}&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;DeleteCommandHandler&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;T&amp;gt; &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; : &lt;span style="color: #ffc66d"&gt;CommandOperationResultHandler&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;DeleteCommand&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;T&amp;gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;readonly&lt;/span&gt; &lt;span style="color: #6897bb"&gt;ISession&lt;/span&gt; session;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;readonly&lt;/span&gt; &lt;span style="color: #6897bb"&gt;ILogger&lt;/span&gt; logger;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; DeleteCommandHandler(&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;DeleteCommand&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;T&amp;gt; command, &lt;/span&gt;&lt;span style="color: #6897bb"&gt;ISession&lt;/span&gt; session, &lt;span style="color: #6897bb"&gt;ILogger&lt;/span&gt; logger) &lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; : &lt;span style="color: #cc7832"&gt;base&lt;/span&gt;(command)&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;this&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.session = session;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;this&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.logger = logger;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;OperationResult&lt;/span&gt; Execute()&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; session.Delete(command.Resource);&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; logger.WriteInfo(&lt;span style="color: #a5c25c"&gt;&amp;quot;Deleted &amp;quot;&lt;/span&gt; + command.Resource);&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;return&lt;/span&gt; &lt;span style="color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;OperationResult&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;SeeOther&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; RedirectLocation = command.RedirectLocation&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; };&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This is how you would issue the delete command from your handler:&lt;/p&gt;  &lt;div style="padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.5em"&gt;   &lt;p style="line-height: 1.2em; margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;ResourceHandler&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;readonly&lt;/span&gt; &lt;span style="color: #6897bb"&gt;ISession&lt;/span&gt; session;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; ResourceHandler(&lt;span style="color: #6897bb"&gt;ISession&lt;/span&gt; session)&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;this&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.session = session;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;OperationResult&lt;/span&gt; Delete(&lt;span style="color: #cc7832"&gt;int&lt;/span&gt; id)&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; resource = session.Get&amp;lt;&lt;span style="color: #ffc66d"&gt;Resource&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;(id);&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;return&lt;/span&gt; &lt;span style="color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;DeleteCommand&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;Resource&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;(resource)&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; RedirectLocation = &lt;span style="color: #cc7832"&gt;typeof&lt;/span&gt;(&lt;span style="color: #ffc66d"&gt;HomeResource&lt;/span&gt;).CreateUri()&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; };&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Last thing we need to do is register our pipeline contributor and command handler so they will be used.&lt;/p&gt;  &lt;div style="padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.5em"&gt;   &lt;p style="line-height: 1.2em; margin: 0px"&gt;&lt;span style="color: #ffc66d"&gt;ResourceSpace&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Uses.PipelineContributor&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;CommandOperationResultInvokerContributor&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;();&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&lt;span style="color: #ffc66d"&gt;ResourceSpace&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Uses.CustomDependency&amp;lt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;CommandOperationResultHandler&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;DeleteCommand&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;Resource&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;&amp;gt;, &lt;/span&gt;&lt;/p&gt;    &lt;p style="line-height: 1.2em; margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;DeleteCommandHandler&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;Resource&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;&amp;gt;(&lt;/span&gt;&lt;span style="color: #6897bb"&gt;DependencyLifetime&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Transient);&lt;/span&gt;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;That’s all there is to it.&lt;/p&gt;  &lt;p&gt;Personally I prefer how this works in &lt;a href="http://www.openrasta.com" target="_blank"&gt;Open Rasta&lt;/a&gt; but then I would say that. I like how the result is manipulated by adding a step to the pipeline rather than having to override behaviour as in MVC. It just seems tidier and more flexible. The other differences in implementation could be transferred and are probably a matter of personal preference.&lt;/p&gt;  &lt;p&gt;Which do you think is better?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-4575421957199331168?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=nHW5zN3faXM:DMlvv55JQ1w:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=nHW5zN3faXM:DMlvv55JQ1w:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=nHW5zN3faXM:DMlvv55JQ1w:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=nHW5zN3faXM:DMlvv55JQ1w:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=nHW5zN3faXM:DMlvv55JQ1w:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=nHW5zN3faXM:DMlvv55JQ1w:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=nHW5zN3faXM:DMlvv55JQ1w:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/nHW5zN3faXM" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/4575421957199331168?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/4575421957199331168?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/nHW5zN3faXM/better-actionresult-open-rasta-edition.html" title="A better ActionResult: Open Rasta edition" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/09896269341967717523</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="17836723317508089121" /></author><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/12/better-actionresult-open-rasta-edition.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0YCQ3o7eyp7ImA9WxBTFE4.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-1080762160407809752</id><published>2009-12-10T08:51:00.001Z</published><updated>2009-12-10T08:52:42.403Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-10T08:52:42.403Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Architecture" /><category scheme="http://www.blogger.com/atom/ns#" term="Rant" /><title>CQRS: Crack for architecture addicts</title><content type="html">&lt;p&gt;I’m getting a bad feeling about yet another high-brow architecture. &lt;a href="http://blog.fohjin.com/blog/2009/11/12/CQRS_a_la_Greg_Young" target="_blank"&gt;CQRS&lt;/a&gt; is a complex solution to a complex problem. &lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;*NEWSFLASH*&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Your problem is not complex enough to warrant the overhead of a complex solution &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;For the 1% of people who can rightly say “but my problem &lt;strong&gt;is&lt;/strong&gt; complex enough” ask yourselves this: is it &lt;strong&gt;really&lt;/strong&gt; that complex? I mean &lt;strong&gt;really&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;Be honest now. Are you jumping at the latest architecture all the cool kids are talking about? Do you have twenty message buses passing data around because your intranet application might need to scale to millions of users one day? If you do, you probably don’t need CQRS for technical reasons but because &lt;strong&gt;you’re an architecture addict&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;If you’ve got this far you either really do need to use CQRS or you have &lt;strong&gt;serious&lt;/strong&gt; problem. So ask yourself this, you’re probably an architect or senior developer. Can &lt;strong&gt;the rest of your team &lt;/strong&gt;fully understand the directions you’ll be giving from your ivory tower? If half of them can’t &lt;strong&gt;you are choosing the wrong architecture&lt;/strong&gt;. I don’t care if it fits your problem perfectly. If your team can’t handle it, &lt;strong&gt;it’s the wrong choice&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;If you still think CQRS is the right solution then you are in a &lt;strong&gt;very&lt;/strong&gt; select group. You have a complex domain, scaling is a big problem for you and you have a team capable of taking the burden of a complex solution. Are you hiring?&lt;/p&gt;  &lt;p&gt;That or you’re &lt;strong&gt;completely deluded&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Or you are a SOA consultant that is selling CQRS as the silver bullet for all development problems. &lt;/p&gt;  &lt;p&gt;And I hate you.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-1080762160407809752?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=eKRZOCbjbgI:yIE1m9ZS54o:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=eKRZOCbjbgI:yIE1m9ZS54o:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=eKRZOCbjbgI:yIE1m9ZS54o:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=eKRZOCbjbgI:yIE1m9ZS54o:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=eKRZOCbjbgI:yIE1m9ZS54o:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=eKRZOCbjbgI:yIE1m9ZS54o:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=eKRZOCbjbgI:yIE1m9ZS54o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/eKRZOCbjbgI" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/1080762160407809752?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/1080762160407809752?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/eKRZOCbjbgI/cqrs-crack-for-architecture-addicts.html" title="CQRS: Crack for architecture addicts" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/09896269341967717523</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="17836723317508089121" /></author><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/12/cqrs-crack-for-architecture-addicts.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4MQ38_eSp7ImA9WxNUF0Q.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-1200464228302377202</id><published>2009-11-09T20:36:00.001Z</published><updated>2009-11-09T20:36:22.141Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-09T20:36:22.141Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="BDD" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="BDD from scratch" /><title>What is BDD (Behaviour Driven Design)?</title><content type="html">&lt;p&gt;“What is BDD?” is a question that’s been doing the rounds lately within the &lt;a href="http://www.altnetgroup.com" target="_blank"&gt;altnetgroup&lt;/a&gt; and &lt;a href="http://search.twitter.com/search?q=%23devbookclub" target="_blank"&gt;devbookclub&lt;/a&gt;. There’s a great deal of mysticism surrounding it as if it were some exclusive members club. I’m going to slay some of the myths and tell you what BDD really is.&lt;/p&gt;  &lt;h3&gt;Myth 1: BDD requires a framework or tool&lt;/h3&gt;  &lt;p&gt;You don’t need to use &lt;a href="http://github.com/machine/machine.specifications" target="_blank"&gt;MSpec&lt;/a&gt;, &lt;a href="http://rspec.info/" target="_blank"&gt;RSpec&lt;/a&gt;, &lt;a href="http://cukes.info/" target="_blank"&gt;Cucumber&lt;/a&gt;, etc to practice BDD. Sure they can help but they are not a precursor to being a practitioner of BDD. You don’t even have to write your tests within a certain construct such as Given-When-Then.&lt;/p&gt;  &lt;h3&gt;Myth 2: BDD requires UAT&lt;/h3&gt;  &lt;p&gt;User Acceptance Testing is a great concept but is one of those practices that only the elite working with an exceptional client get to do in real life. If you have UAT as part of your process, all power to you, but that’s all it is, part of your process. It is not part of BDD. It is merely coincidental that BDD style tests are the best way to express your acceptance tests.&lt;/p&gt;  &lt;h3&gt;Myth 3: BDD has to be done top-down&lt;/h3&gt;  &lt;p&gt;It is easier to approach BDD in a top down manner. But much like its easier to put your underwear on first, that doesn’t work for everyone in every situation. Just ask Superman. The proponents of BDD often state things in a radical fashion due to a fear of BDD being thrown in the same pot as TDD. That doesn’t mean that every time they say “you must” they actually mean it.&lt;/p&gt;  &lt;h3&gt;So what is BDD?&lt;/h3&gt;  &lt;p&gt;At its core, BDD is TDD done with a specific mindset; testing the intent of the system rather than testing a particular piece of code. The difference is subtle but the effects are large. There’s &lt;a href="http://en.wikipedia.org/wiki/Neuro-linguistic_programming" target="_blank"&gt;an entire discipline dedicated to the power of semantics&lt;/a&gt; after all.&lt;/p&gt;  &lt;p&gt;It is the difference between “when I add a new post to my blog, the new post shows up on my homepage” and “calling the create new post method on the blog controller saves a new post and the new post is passed to the homepage view when the home controller’s index action is called”. Both sentences describe the same code, the BDD style signals the intent and is decoupled from the implementation. The non-BDD style describes what the code is doing almost line for line. The decoupling of the tests from the implementation is where the largest benefit of BDD comes from. Your tests will be less brittle making refactoring easier, perhaps even fun, making your code more malleable.&lt;/p&gt;  &lt;p&gt;The myths aren’t completely unfounded, using constructs such as Given-When-Then helps enforce the required mindset. Frameworks such as MSpec, RSpec, Cucumber or even &lt;a href="http://blog.robustsoftware.co.uk/2009/09/bdd-from-scratch-build-your-own.html" target="_blank"&gt;a bespoke one&lt;/a&gt; help you write tests within that construct. Working from the top-down helps you work from the behaviour of the user interface down to the behaviour of the data access. UAT helps you drive the behaviour of the system from the requirements of the client.&lt;/p&gt;  &lt;p&gt;That’s all these things do though, help you develop in the BDD style. You can still write your code in a non-BDD style using all these frameworks, tools and processes, just as you can develop in the BDD style using none of them.&lt;/p&gt;  &lt;h4&gt;BDD is a state of mind.&lt;/h4&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-1200464228302377202?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bjoKk42XVyA:xPJU4v7RYMU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=bjoKk42XVyA:xPJU4v7RYMU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bjoKk42XVyA:xPJU4v7RYMU:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bjoKk42XVyA:xPJU4v7RYMU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=bjoKk42XVyA:xPJU4v7RYMU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bjoKk42XVyA:xPJU4v7RYMU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bjoKk42XVyA:xPJU4v7RYMU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/bjoKk42XVyA" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/1200464228302377202?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/1200464228302377202?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/bjoKk42XVyA/what-is-bdd-behaviour-driven-design.html" title="What is BDD (Behaviour Driven Design)?" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/09896269341967717523</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="17836723317508089121" /></author><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/11/what-is-bdd-behaviour-driven-design.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEMRHczeSp7ImA9WxNRGEs.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-3844629243516606702</id><published>2009-09-13T17:51:00.001+01:00</published><updated>2009-09-13T17:51:25.981+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-13T17:51:25.981+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="BDD from scratch" /><category scheme="http://www.blogger.com/atom/ns#" term="Quality" /><title>BDD from scratch – Build your own framework (Part 2)</title><content type="html">&lt;p&gt;In part one I covered how to &lt;a href="http://blog.robustsoftware.co.uk/2009/09/bdd-from-scratch-build-your-own.html" target="_blank"&gt;organise your tests into the Given-When-Then style&lt;/a&gt; through the use of an abstract base class. In this post I’m going to show how you can manage your mocks more efficiently. Though not really a part of &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; I’ve found it very useful in clarifying the behaviour described in my tests as it reduces the amount of noise caused by the definition of variables.&lt;/p&gt;  &lt;p&gt;I’m going to walk you through an example test, starting off with what we finished off with in part 1. We are going to be testing this standard ASP.NET MVC controller method:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.WebApplication.Controllers&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BooksController&lt;/span&gt; : &lt;span style="font-weight: bold; color: #ffc66d"&gt;Controller&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;readonly&lt;/span&gt; &lt;span style="font-weight: bold; color: #6897bb"&gt;IBookService&lt;/span&gt; bookService;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;readonly&lt;/span&gt; &lt;span style="font-weight: bold; color: #6897bb"&gt;IAuthenticationService&lt;/span&gt; authenticationService;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; BooksController(&lt;span style="font-weight: bold; color: #6897bb"&gt;IBookService&lt;/span&gt; bookService, &lt;span style="font-weight: bold; color: #6897bb"&gt;IAuthenticationService&lt;/span&gt; authenticationService)&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;this&lt;/span&gt;.bookService = bookService;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;this&lt;/span&gt;.authenticationService = authenticationService;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;ViewResult&lt;/span&gt; YourBooks()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;var&lt;/span&gt; currentUser = authenticationService.CurrentUser();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ViewData.Model = bookService.OwnedBy(currentUser);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;return&lt;/span&gt; View(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;YourBooks&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;I’m going to be using &lt;a href="http://code.google.com/p/moq/" target="_blank"&gt;Moq&lt;/a&gt; as my mocking framework for this test; again I’ve applied the same concept to other frameworks such as &lt;a href="http://ayende.com/projects/rhino-mocks.aspx" target="_blank"&gt;Rhino Mocks&lt;/a&gt;. Here is how our test starts out:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.WebApplication.Test.Controllers.Books&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;DisplayingYourBooks&lt;/span&gt; : &lt;span style="font-weight: bold; color: #ffc66d"&gt;BehaviourTest&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;MockFactory&lt;/span&gt; factory;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BooksController&lt;/span&gt; controller;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IBookService&lt;/span&gt;&amp;gt; bookService;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IAuthenticationService&lt;/span&gt;&amp;gt; authenticationService;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;ViewResult&lt;/span&gt; result;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #ffc66d"&gt;Book&lt;/span&gt;&amp;gt; yourBooks;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;User&lt;/span&gt; currentUser;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Given()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; factory = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;MockFactory&lt;/span&gt;(&lt;span style="font-weight: bold; color: #6897bb"&gt;MockBehavior&lt;/span&gt;.Loose);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; bookService = factory.Create&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IBookService&lt;/span&gt;&amp;gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; authenticationService = factory.Create&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IAuthenticationService&lt;/span&gt;&amp;gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; yourBooks = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #ffc66d"&gt;Book&lt;/span&gt;&amp;gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; currentUser = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;User&lt;/span&gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; authenticationService.Setup(x =&amp;gt; x.CurrentUser()).Returns(currentUser);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; bookService.Setup(x =&amp;gt; x.OwnedBy(currentUser)).Returns(yourBooks);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; controller = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BooksController&lt;/span&gt;(bookService.Object, authenticationService.Object);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; When()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result = controller.YourBooks();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; ShownYourBooksView()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;YourBooks&amp;quot;&lt;/span&gt;, result.ViewName);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; PassedListOfYourBooks()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.AreSame(yourBooks, result.ViewData.Model);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;The obvious step to reduce the amount of test code on display would be to move the setup of the MockFactory up into the base class. We’re going to take it a step further than that though and introduce a mock management class. Here is what it looks like:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.Framework&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;MockManager&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;readonly&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;MockFactory&lt;/span&gt; factory;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;readonly&lt;/span&gt; &lt;span style="font-weight: bold; color: #6897bb"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #ffc66d"&gt;Type&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;object&lt;/span&gt;&amp;gt; mockDictionary;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; MockManager()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; factory = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;MockFactory&lt;/span&gt;(&lt;span style="font-weight: bold; color: #6897bb"&gt;MockBehavior&lt;/span&gt;.Loose);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mockDictionary = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #ffc66d"&gt;Type&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;object&lt;/span&gt;&amp;gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Mock&lt;/span&gt;&amp;lt;T&amp;gt; Mock&amp;lt;T&amp;gt;() &lt;span style="font-weight: bold; color: #cc7832"&gt;where&lt;/span&gt; T : &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;var&lt;/span&gt; type = &lt;span style="font-weight: bold; color: #cc7832"&gt;typeof&lt;/span&gt;(T);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;if&lt;/span&gt; (!mockDictionary.ContainsKey(type))&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mockDictionary.Add(type, factory.Create&amp;lt;T&amp;gt;());&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;return&lt;/span&gt; mockDictionary[type] &lt;span style="font-weight: bold; color: #cc7832"&gt;as&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Mock&lt;/span&gt;&amp;lt;T&amp;gt;;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This is a wrapper around a dictionary of mock objects. When we ask for a mock that has not been requested before, one is created. Otherwise, the previously created mock is retrieved from the dictionary and returned. We’ll add the creation of the mock manager to our abstract base class and expose the Mock&amp;lt;T&amp;gt; method for use within our tests:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.Framework&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;TestFixture&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;abstract&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BehaviourTest&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;MockManager&lt;/span&gt; mockManager;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Mock&lt;/span&gt;&amp;lt;T&amp;gt; Mock&amp;lt;T&amp;gt;() &lt;span style="font-weight: bold; color: #cc7832"&gt;where&lt;/span&gt; T : &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;return&lt;/span&gt; mockManager.Mock&amp;lt;T&amp;gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;TestFixtureSetUp&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Setup()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mockManager = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;MockManager&lt;/span&gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Given();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; When();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;abstract&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Given();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;abstract&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; When();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Now we can utilise the mock manager within our original test, reducing the lines of code considerably:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.WebApplication.Test.Controllers.Books&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;DisplayingYourBooks&lt;/span&gt; : &lt;span style="font-weight: bold; color: #ffc66d"&gt;BehaviourTest&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BooksController&lt;/span&gt; controller;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;ViewResult&lt;/span&gt; result;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #ffc66d"&gt;Book&lt;/span&gt;&amp;gt; yourBooks;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;User&lt;/span&gt; currentUser;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Given()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; yourBooks = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #ffc66d"&gt;Book&lt;/span&gt;&amp;gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; currentUser = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;User&lt;/span&gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Mock&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IAuthenticationService&lt;/span&gt;&amp;gt;().Setup(x =&amp;gt; x.CurrentUser()).Returns(currentUser);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Mock&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IBookService&lt;/span&gt;&amp;gt;().Setup(x =&amp;gt; x.OwnedBy(currentUser)).Returns(yourBooks);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; controller = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BooksController&lt;/span&gt;(Mock&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IBookService&lt;/span&gt;&amp;gt;().Object, Mock&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IAuthenticationService&lt;/span&gt;&amp;gt;().Object);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; When()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result = controller.YourBooks();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; ShownYourBooksView()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;YourBooks&amp;quot;&lt;/span&gt;, result.ViewName);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; PassedListOfYourBooks()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.AreSame(yourBooks, result.ViewData.Model);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;As we no longer have to worry about variable declaration and assignment for our mocks, we can leave the test code to signal the intent of our test. As there is no real setup for the fields currentUser and yourBooks, I’d be tempted to in-line those variables but this is a matter of personal taste:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.WebApplication.Test.Controllers.Books&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;DisplayingYourBooks&lt;/span&gt; : &lt;span style="font-weight: bold; color: #ffc66d"&gt;BehaviourTest&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BooksController&lt;/span&gt; controller;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;ViewResult&lt;/span&gt; result;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #ffc66d"&gt;Book&lt;/span&gt;&amp;gt; yourBooks = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="font-weight: bold; color: #ffc66d"&gt;Book&lt;/span&gt;&amp;gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;User&lt;/span&gt; currentUser = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;User&lt;/span&gt;();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Given()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Mock&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IAuthenticationService&lt;/span&gt;&amp;gt;().Setup(x =&amp;gt; x.CurrentUser()).Returns(currentUser);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Mock&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IBookService&lt;/span&gt;&amp;gt;().Setup(x =&amp;gt; x.OwnedBy(currentUser)).Returns(yourBooks);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; controller = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BooksController&lt;/span&gt;(Mock&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IBookService&lt;/span&gt;&amp;gt;().Object, Mock&amp;lt;&lt;span style="font-weight: bold; color: #6897bb"&gt;IAuthenticationService&lt;/span&gt;&amp;gt;().Object);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; When()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result = controller.YourBooks();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; ShownYourBooksView()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;YourBooks&amp;quot;&lt;/span&gt;, result.ViewName);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; PassedListOfYourBooks()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.AreSame(yourBooks, result.ViewData.Model);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;As you can see, this reduces the amount of code required to establish the same context to test a given behaviour. The less lines of code you need to set up a test, the easier it is going to be to understand that test in the future. This, along with the more explanatory naming of your test, makes it much easier to maintain that test in the future.&lt;/p&gt;  &lt;p&gt;Next up, I’ll show how we can utilise our MockManager to implement auto mocking. This will reduce the amount of code in our test slightly, but more importantly it makes our test suite less brittle.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Related posts&lt;/em&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/09/bdd-from-scratch-build-your-own.html" target="_blank"&gt;BDD from scratch - Part 1&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/05/difference-between-areequal-and-aresame.html" target="_blank"&gt;Difference between AreEqual and AreSame&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/02/test-aided-development.html" target="_blank"&gt;Test aided development&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-3844629243516606702?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=o3HfdRYSpHI:Hy0R_pD3vpA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=o3HfdRYSpHI:Hy0R_pD3vpA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=o3HfdRYSpHI:Hy0R_pD3vpA:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=o3HfdRYSpHI:Hy0R_pD3vpA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=o3HfdRYSpHI:Hy0R_pD3vpA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=o3HfdRYSpHI:Hy0R_pD3vpA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=o3HfdRYSpHI:Hy0R_pD3vpA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/o3HfdRYSpHI" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3844629243516606702?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3844629243516606702?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/o3HfdRYSpHI/bdd-from-scratch-build-your-own_13.html" title="BDD from scratch – Build your own framework (Part 2)" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/09/bdd-from-scratch-build-your-own_13.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcGSXg6cCp7ImA9WxNREkg.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-9068096885841795344</id><published>2009-09-06T16:00:00.000+01:00</published><updated>2009-09-06T17:20:28.618+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-06T17:20:28.618+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="BDD from scratch" /><category scheme="http://www.blogger.com/atom/ns#" term="Quality" /><title>BDD from scratch – Build your own framework (Part 1)</title><content type="html">&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; is a higher level of unit testing, it creates better documentation of your system by recording its intent which makes your system easier to learn for new developers and relearn for when you revisit your code further down the line.&lt;/p&gt;  &lt;p&gt;I’m going to show you how to build your own &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; testing framework on top of a vanilla unit testing framework. For my example I’m going to use &lt;a href="http://www.nunit.org/" target="_blank"&gt;NUnit&lt;/a&gt; but I’ve applied the same principles with &lt;a href="http://www.mbunit.com/" target="_blank"&gt;MbUnit&lt;/a&gt;, &lt;a href="http://www.codeplex.com/xunit" target="_blank"&gt;xUnit&lt;/a&gt; and it should work with any other unit testing framework too. &lt;/p&gt;  &lt;p&gt;What’s good about doing things this way, as opposed to using a purpose built BDD framework like &lt;a href="http://github.com/machine/machine.specifications/tree/master" target="_blank"&gt;MSpec&lt;/a&gt;, is that it allows your tests to exist and be run side-by-side with traditional unit tests. This can ease the migration to the new style if you’re all moving over to it and it lets you write tests in the &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; style for some parts of the system whilst sticking with the traditional unit style for other parts. Though I’ll be amazed if you don’t end up writing all your tests in the &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; style as everyone I’ve shown it too loves it.&lt;/p&gt;  &lt;p&gt;I’ll show you how to create the basis for your own &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; framework and I’ll give an example of how a &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; style test looks in comparison to a traditional unit test.&lt;/p&gt;  &lt;h3&gt;What is BDD all about?&lt;/h3&gt;  &lt;p&gt;The core concept of &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; is Given-When-Then (often referred to as Arrange-Act-Assert):&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;Given&lt;/strong&gt; the system is in a certain state (the context of the test) &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;When&lt;/strong&gt; an action is performed on the system (normally calling a single method) &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Then&lt;/strong&gt; a list of assertions should be satisfied &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Herein lies another fundamental difference with &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt;, you will create a test fixture per &lt;strong&gt;scenario&lt;/strong&gt; rather than a fixture per class as it common with traditional unit testing.&lt;/p&gt;  &lt;h3&gt;The basis of our framework&lt;/h3&gt;  &lt;p&gt;The way to transform your standard unit testing framework to a &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; one is to use an &lt;strong&gt;abstract base class&lt;/strong&gt;. This will modify how your tests are run, giving you the ability to specify your &lt;strong&gt;Given&lt;/strong&gt;, &lt;strong&gt;When&lt;/strong&gt; and corresponding &lt;strong&gt;Thens&lt;/strong&gt; separately from one another:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;using&lt;/span&gt; NUnit.Framework;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.Framework&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;TestFixture&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;abstract&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BehaviourTest&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;TestFixtureSetUp&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Setup()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Given();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; When();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;abstract&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Given();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;abstract&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; When();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This means that the contents of your &lt;strong&gt;Given&lt;/strong&gt; and &lt;strong&gt;When&lt;/strong&gt; methods will be run &lt;strong&gt;once&lt;/strong&gt; before each of your methods decorated with the &lt;strong&gt;Test&lt;/strong&gt; attribute are run. This is important as it means that all your assertions should not have side effects (this should be the case already). You will use it in a test class by doing something like this:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;using&lt;/span&gt; System;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;using&lt;/span&gt; NUnit.Framework;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.Framework&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;ExampleBehaviour&lt;/span&gt; : &lt;span style="font-weight: bold; color: #ffc66d"&gt;BehaviourTest&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Given()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: gray"&gt;// the system is setup in a certain state&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; When()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: gray"&gt;// a defined action is performed on the system&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; ThisAssertionShouldBeSatisfied()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.IsTrue(&lt;span style="font-weight: bold; color: #cc7832"&gt;true&lt;/span&gt;);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; AnotherAssertionShouldBeSatisfied()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.IsTrue(&lt;span style="font-weight: bold; color: #cc7832"&gt;true&lt;/span&gt;);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Notice that the intent verified by each assertion is documented in the name of the test method. This means that when you run your tests, the name of the tests themselves show you when was meant to happen rather than the error messages that most people forget to add to their assertions.&lt;/p&gt;  &lt;p&gt;Another thing that I like to do but is entirely optional is alias the Test attribute to be able to use a &lt;strong&gt;Then&lt;/strong&gt; attribute with the same behaviour:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;using&lt;/span&gt; NUnit.Framework;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.Framework&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;ThenAttribute&lt;/span&gt; : &lt;span style="font-weight: bold; color: #ffc66d"&gt;TestAttribute&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This just changes the original example test slightly so it’s more obvious how the Given-When-Then style is being applied:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;using&lt;/span&gt; System;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;using&lt;/span&gt; NUnit.Framework;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;namespace&lt;/span&gt; RobustSoftware.BddFromScratch.Framework&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;ExampleBehaviour&lt;/span&gt; : &lt;span style="font-weight: bold; color: #ffc66d"&gt;BehaviourTest&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Given()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: gray"&gt;// the system is setup in a certain state&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; When()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: gray"&gt;// a defined action is performed on the system&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; ThisAssertionShouldBeSatisfied()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.IsTrue(&lt;span style="font-weight: bold; color: #cc7832"&gt;true&lt;/span&gt;);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; AnotherAssertionShouldBeSatisfied()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.IsTrue(&lt;span style="font-weight: bold; color: #cc7832"&gt;true&lt;/span&gt;);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;h3&gt;Converting a traditional test&lt;/h3&gt;  &lt;p&gt;I’ll start of with what I think to be a pretty standard unit test that I found in the source of &lt;a href="http://trac.caffeine-it.com/openrasta"&gt;OpenRasta&lt;/a&gt;:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;[&lt;span style="font-weight: bold; color: #ffc66d"&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; a_change_after_a_creation_results_in_a_new_oject_with_the_same_properties()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;var&lt;/span&gt; binder = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;KeyedValuesBinder&lt;/span&gt;(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;customer&amp;quot;&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;typeof&lt;/span&gt;(&lt;span style="font-weight: bold; color: #ffc66d"&gt;Customer&lt;/span&gt;));&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; binder.SetProperty(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;username&amp;quot;&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt;[] { &lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;johndoe&amp;quot;&lt;/span&gt; }, (str, type) =&amp;gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BindingResult&lt;/span&gt;.Success(str));&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; binder.BuildObject();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; binder.SetProperty(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;firstname&amp;quot;&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt;[] {&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;john&amp;quot;&lt;/span&gt;}, (str, type) =&amp;gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BindingResult&lt;/span&gt;.Success(str));&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;var&lt;/span&gt; customer = (&lt;span style="font-weight: bold; color: #ffc66d"&gt;Customer&lt;/span&gt;)binder.BuildObject().Instance;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; customer.Username.ShouldBe(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;johndoe&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; customer.FirstName.ShouldBe(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;john&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;As I see it this, like many other traditional unit tests, is already split into the Given-When-Then style logically:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;[&lt;span style="font-weight: bold; color: #ffc66d"&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; a_change_after_a_creation_results_in_a_new_oject_with_the_same_properties()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: gray"&gt;// Given - the context we are establishing in the system&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;var&lt;/span&gt; binder = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;KeyedValuesBinder&lt;/span&gt;(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;customer&amp;quot;&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;typeof&lt;/span&gt;(&lt;span style="font-weight: bold; color: #ffc66d"&gt;Customer&lt;/span&gt;));&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; binder.SetProperty(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;username&amp;quot;&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt;[] { &lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;johndoe&amp;quot;&lt;/span&gt; }, (str, type) =&amp;gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BindingResult&lt;/span&gt;.Success(str));&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; binder.BuildObject();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; binder.SetProperty(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;firstname&amp;quot;&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt;[] {&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;john&amp;quot;&lt;/span&gt;}, (str, type) =&amp;gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BindingResult&lt;/span&gt;.Success(str));&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: gray"&gt;// When - the action we are performing on the system&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;var&lt;/span&gt; customer = (&lt;span style="font-weight: bold; color: #ffc66d"&gt;Customer&lt;/span&gt;)binder.BuildObject().Instance;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: gray"&gt;// Then - checking the system ends up in the desired state&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; customer.Username.ShouldBe(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;johndoe&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; customer.FirstName.ShouldBe(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;john&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;So splitting it physically into the separate sections is not much of a leap:&lt;/p&gt;  &lt;div style="padding-right: 0.4em; padding-left: 0.4em; font-size: 10pt; background: #272727; padding-bottom: 0.4em; color: white; line-height: 1.2em; padding-top: 0.4em; font-family: consolas"&gt;   &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;ChangingAnObjectAfterACreation&lt;/span&gt; : &lt;span style="font-weight: bold; color: #ffc66d"&gt;BehaviourTest&lt;/span&gt;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;{&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;KeyedValuesBinder&lt;/span&gt; binder;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Customer&lt;/span&gt; customer;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; Given()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; binder = &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;KeyedValuesBinder&lt;/span&gt;(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;customer&amp;quot;&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;typeof&lt;/span&gt;(&lt;span style="font-weight: bold; color: #ffc66d"&gt;Customer&lt;/span&gt;));&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; binder.SetProperty(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;username&amp;quot;&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt;[] { &lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;johndoe&amp;quot;&lt;/span&gt; }, (str, type) =&amp;gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BindingResult&lt;/span&gt;.Success(str));&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; binder.BuildObject();&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; binder.SetProperty(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;firstname&amp;quot;&lt;/span&gt;, &lt;span style="font-weight: bold; color: #cc7832"&gt;new&lt;/span&gt;[] { &lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;john&amp;quot;&lt;/span&gt; }, (str, type) =&amp;gt; &lt;span style="font-weight: bold; color: #ffc66d"&gt;BindingResult&lt;/span&gt;.Success(str));&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; When()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; customer = (&lt;span style="font-weight: bold; color: #ffc66d"&gt;Customer&lt;/span&gt;) binder.BuildObject().Instance;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; UsernameShouldBeJohnDoe()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;johndoe&amp;quot;&lt;/span&gt;, customer.Username);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="font-weight: bold; color: #ffc66d"&gt;Then&lt;/span&gt;]&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold; color: #cc7832"&gt;void&lt;/span&gt; FirstNameShouldBeJohn()&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="font-weight: bold; color: #ffc66d"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="font-weight: bold; color: #a5c25c"&gt;&amp;quot;john&amp;quot;&lt;/span&gt;, customer.FirstName);&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;I've dropped the use of the assertion extension methods that &lt;a href="http://twitter.com/serialseb"&gt;Sebastien Lambla&lt;/a&gt; was using (I’ll cover how to write those later in the series), but otherwise the actual test code has remained the same.&lt;/p&gt;  &lt;p&gt;The physical separation of the logical parts of the test makes the test easier to follow and the assertions at least as explicit even without the extension methods being used.&lt;/p&gt;  &lt;p&gt;The fact that &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; makes the separation many people already make when writing traditional unit tests more explicit is why I and other people like it. It makes your tests more readable as you can often skim the Given section as that should be conveyed by the name of the entire fixture. That leaves you to see what method is being called and the assertions being made. These are often now more descriptive as they are given a method name.&lt;/p&gt;  &lt;p&gt;If you’ve got any questions, leave a comment and I’ll reply as soon as I can. Do the same if you’ve any related topics you’d like to see covered. I’m planning on covering, mock management, auto-mocking, fluent test extensions and shared contexts.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Related posts&lt;/em&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/08/if-your-code-isn-tested-it-doesn-work.html" target="_blank"&gt;If your code isn't tested it doesn't work&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/02/test-aided-development.html" target="_blank"&gt;Test aided development&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-9068096885841795344?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=qWLlsPzO_SM:_DZbimUlnXQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=qWLlsPzO_SM:_DZbimUlnXQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=qWLlsPzO_SM:_DZbimUlnXQ:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=qWLlsPzO_SM:_DZbimUlnXQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=qWLlsPzO_SM:_DZbimUlnXQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=qWLlsPzO_SM:_DZbimUlnXQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=qWLlsPzO_SM:_DZbimUlnXQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/qWLlsPzO_SM" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/9068096885841795344?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/9068096885841795344?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/qWLlsPzO_SM/bdd-from-scratch-build-your-own.html" title="BDD from scratch – Build your own framework (Part 1)" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/09/bdd-from-scratch-build-your-own.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMFRnw8eSp7ImA9WxNTFkU.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-490508894547929906</id><published>2009-08-19T13:53:00.001+01:00</published><updated>2009-08-19T13:53:37.271+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-19T13:53:37.271+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="Quality" /><title>If your code isn't tested, it doesn't work</title><content type="html">&lt;p&gt;I test-drive my code. That means, by definition, that each line is covered by at least one test. I know my code works today and tests ensure it still works tomorrow, next week and next year.&lt;/p&gt;  &lt;p&gt;If your code isn't tested you may know it works today, after drawn-out manual testing through each scenario. But what about tomorrow? Are you going to do the manual tests for today's work? Come next week are you going to be performing manual tests for this week's work? Of course you're not, you'd never get anything done.&lt;/p&gt;  &lt;p&gt;By testing your code you are eliminating the majority of emergent bugs as soon as they happen (you are doing continuous integration aren't you?). This means you produce features faster in the medium to long term as you minimise the number of bugs that arise. A win for business as costs are reduced as well as lead time. I don't know about you but I prefer adding features to chasing bugs too. &lt;/p&gt;  &lt;p&gt;If you're not testing, you must enjoy debugging.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-490508894547929906?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=CciCOVlUmD8:zFXFzcumINY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=CciCOVlUmD8:zFXFzcumINY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=CciCOVlUmD8:zFXFzcumINY:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=CciCOVlUmD8:zFXFzcumINY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=CciCOVlUmD8:zFXFzcumINY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=CciCOVlUmD8:zFXFzcumINY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=CciCOVlUmD8:zFXFzcumINY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/CciCOVlUmD8" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/490508894547929906?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/490508894547929906?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/CciCOVlUmD8/if-your-code-isn-tested-it-doesn-work.html" title="If your code isn&amp;#39;t tested, it doesn&amp;#39;t work" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/09896269341967717523</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="17836723317508089121" /></author><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/08/if-your-code-isn-tested-it-doesn-work.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIMQX49cSp7ImA9WxJaE00.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-3524433336717462490</id><published>2009-08-03T12:54:00.002+01:00</published><updated>2009-08-03T12:56:20.069+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-03T12:56:20.069+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><title>A better domain event raiser</title><content type="html">&lt;p&gt;There was a lot of discussion about domain events at &lt;a href="http://altnetuk.com/"&gt;AltNetUK&lt;/a&gt; around &lt;a href="http://msdn.microsoft.com/en-us/magazine/ee236415.aspx"&gt;Udi Dahan's recent article&lt;/a&gt;. Please read that first so that you’ll know the context of what I’m about to say, I’ll still be here. Might be useful to have them side-by-side.&lt;/p&gt;  &lt;p&gt;I couldn’t help when reading it that the code around event dispatching was quite a mess, with code added in for multiple, distinct scenarios (live and test). This may just have been to help with the formatting of the article, but it leaves a lot to be desired. &lt;/p&gt;  &lt;p&gt;What I’m going to do here is show my refactored version of the code and explain why I think it is better. What I’m going to be doing is utilising the &lt;a href="http://en.wikipedia.org/wiki/Strategy_pattern"&gt;strategy pattern&lt;/a&gt; to separate the logic of dispatching events from the action of requesting an event to be dispatched.&lt;/p&gt;  &lt;p&gt;In figure 1 of &lt;a href="http://msdn.microsoft.com/en-us/magazine/ee236415.aspx#id0400104"&gt;the testability section&lt;/a&gt; Udi shows how the DomainEvents class ends up. Here is how mine looks after the refactoring:&lt;/p&gt; &lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red204\green120\blue50;\red39\green39\blue39;\red255\green255\blue255;\red255\green198\blue109;\red104\green151\blue187;}??\fs20 \cf1\cb2\highlight2 {\b public}\cf3 {\b  }\cf1 {\b static}\cf3 {\b  }\cf1 {\b class}\cf3 {\b  }\cf4 {\b DomainEvent}\par ??\cf3 {\b \{}\par ??{\b     }\cf1 {\b public}\cf3 {\b  }\cf1 {\b static}\cf3 {\b  }\cf5 {\b IEventDispatcher}\cf3 {\b  Dispatcher \{ }\cf1 {\b get}\cf3 {\b ; }\cf1 {\b set}\cf3 {\b ; \}}\par ??\par ??{\b     }\cf1 {\b public}\cf3 {\b  }\cf1 {\b static}\cf3 {\b  }\cf1 {\b void}\cf3 {\b  Raise&amp;lt;TEvent&amp;gt;(TEvent eventToRaise) }\cf1 {\b where}\cf3 {\b  TEvent : }\cf5 {\b IEvent}\par ??\cf3 {\b     \{}\par ??{\b         Dispatcher.Dispatch(eventToRaise);}\par ??{\b     \}}\par ??{\b \}}}&lt;br /&gt;--&gt;  &lt;div style="padding-bottom: 0.4em; line-height: 1.1em; padding-left: 0.4em; padding-right: 0.4em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.4em"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;static&lt;/span&gt; &lt;span style="color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;DomainEvent&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;static&lt;/span&gt; &lt;span style="color: #6897bb"&gt;IEventDispatcher&lt;/span&gt; Dispatcher { &lt;span style="color: #cc7832"&gt;get&lt;/span&gt;; &lt;span style="color: #cc7832"&gt;set&lt;/span&gt;; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;static&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; Raise&amp;lt;TEvent&amp;gt;(TEvent eventToRaise) &lt;span style="color: #cc7832"&gt;where&lt;/span&gt; TEvent : &lt;span style="color: #6897bb"&gt;IEvent&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Dispatcher.Dispatch(eventToRaise);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This is made possible because I’ve abstracted the dispatching of the event into a separate class implementing the IEventDispatcher interface:&lt;/p&gt; &lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red204\green120\blue50;\red39\green39\blue39;\red255\green255\blue255;\red104\green151\blue187;}??\fs20 \cf1\cb2\highlight2 {\b public}\cf3 {\b  }\cf1 {\b interface}\cf3 {\b  }\cf4 {\b IEventDispatcher}\par ??\cf3 {\b \{}\par ??{\b     }\cf1 {\b void}\cf3 {\b  Dispatch&amp;lt;TEvent&amp;gt;(TEvent eventToDispatch) }\cf1 {\b where}\cf3 {\b  TEvent : }\cf4 {\b IEvent}\cf3 {\b ;}\par ??{\b \}}}&lt;br /&gt;--&gt;  &lt;div style="padding-bottom: 0.4em; line-height: 1.1em; padding-left: 0.4em; padding-right: 0.4em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.4em"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;interface&lt;/span&gt; &lt;span style="color: #6897bb"&gt;IEventDispatcher&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; Dispatch&amp;lt;TEvent&amp;gt;(TEvent eventToDispatch) &lt;span style="color: #cc7832"&gt;where&lt;/span&gt; TEvent : &lt;span style="color: #6897bb"&gt;IEvent&lt;/span&gt;;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;There would be two implementations of IEventDispatcher in normal projects. One to be used at runtime such as this one utilising StructureMap:&lt;/p&gt; &lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red204\green120\blue50;\red39\green39\blue39;\red255\green255\blue255;\red255\green198\blue109;\red104\green151\blue187;}??\fs20 \cf1\cb2\highlight2 {\b public}\cf3 {\b  }\cf1 {\b class}\cf3 {\b  }\cf4 {\b StructureMapEventDispatcher}\cf3 {\b  : }\cf5 {\b IEventDispatcher}\par ??\cf3 {\b \{}\par ??{\b     }\cf1 {\b public}\cf3 {\b  }\cf1 {\b void}\cf3 {\b  Dispatch&amp;lt;TEvent&amp;gt;(TEvent eventToDispatch) }\cf1 {\b where}\cf3 {\b  TEvent : }\cf5 {\b IEvent}\par ??\cf3 {\b     \{}\par ??{\b         }\cf1 {\b foreach}\cf3 {\b  (}\cf1 {\b var}\cf3 {\b  handler }\cf1 {\b in}\cf3 {\b  }\cf4 {\b ObjectFactory}\cf3 .GetAllInstances&amp;lt;\cf5 {\b IEventHandler}\cf3 &amp;lt;TEvent&amp;gt;&amp;gt;())\par ??{\b         \{}\par ??{\b             handler.Handle(eventToDispatch);}\par ??{\b         \}}\par ??{\b     \}}\par ??{\b \}}}&lt;br /&gt;--&gt;  &lt;div style="padding-bottom: 0.4em; line-height: 1.1em; padding-left: 0.4em; padding-right: 0.4em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.4em"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;StructureMapEventDispatcher&lt;/span&gt; : &lt;span style="color: #6897bb"&gt;IEventDispatcher&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; Dispatch&amp;lt;TEvent&amp;gt;(TEvent eventToDispatch) &lt;span style="color: #cc7832"&gt;where&lt;/span&gt; TEvent : &lt;span style="color: #6897bb"&gt;IEvent&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;foreach&lt;/span&gt; (&lt;span style="color: #cc7832"&gt;var&lt;/span&gt; handler &lt;span style="color: #cc7832"&gt;in&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;ObjectFactory&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.GetAllInstances&amp;lt;&lt;/span&gt;&lt;span style="color: #6897bb"&gt;IEventHandler&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;TEvent&amp;gt;&amp;gt;())&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; handler.Handle(eventToDispatch);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;And one to be used during unit tests such as this one:&lt;/p&gt; &lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red204\green120\blue50;\red39\green39\blue39;\red255\green255\blue255;\red255\green198\blue109;\red104\green151\blue187;\red128\green128\blue128;}??\fs20 \cf1\cb2\highlight2 {\b public}\cf3 {\b  }\cf1 {\b class}\cf3 {\b  }\cf4 {\b ActionEventDispatcher}\cf3 {\b  : }\cf5 {\b IEventDispatcher}\par ??\cf3 {\b \{}\par ??{\b     }\cf1 {\b private}\cf3 {\b  }\cf1 {\b readonly}\cf3 {\b  }\cf5 {\b IDictionary}\cf3 &amp;lt;\cf4 {\b Type}\cf3 {\b , }\cf4 {\b Delegate}\cf3 &amp;gt; handlers;\par ??\par ??{\b     }\cf1 {\b public}\cf3 {\b  ActionEventDispatcher()}\par ??{\b     \{}\par ??{\b         handlers = }\cf1 {\b new}\cf3 {\b  }\cf4 {\b Dictionary}\cf3 &amp;lt;\cf4 {\b Type}\cf3 {\b , }\cf4 {\b Delegate}\cf3 &amp;gt;();\par ??{\b     \}}\par ??\par ??{\b     }\cf1 {\b public}\cf3 {\b  }\cf1 {\b void}\cf3 {\b  Register&amp;lt;TEvent&amp;gt;(}\cf5 {\b Action}\cf3 &amp;lt;TEvent&amp;gt; eventAction) \cf1 {\b where}\cf3 {\b  TEvent : }\cf5 {\b IEvent}\par ??\cf3 {\b     \{}\par ??{\b         }\cf6 {\b // assuming you'll only register once per test}\par ??\cf3 {\b         handlers.Add(}\cf1 {\b typeof}\cf3 {\b (TEvent), eventAction);}\par ??{\b     \}}\par ??\par ??{\b     }\cf1 {\b public}\cf3 {\b  }\cf1 {\b void}\cf3 {\b  Dispatch&amp;lt;TEvent&amp;gt;(TEvent eventToDispatch) }\cf1 {\b where}\cf3 {\b  TEvent : }\cf5 {\b IEvent}\par ??\cf3 {\b     \{}\par ??{\b         }\cf1 {\b if}\cf3 {\b  (!handlers.ContainsKey(}\cf1 {\b typeof}\cf3 {\b  (TEvent))) }\cf1 {\b return}\cf3 {\b ;}\par ??\par ??{\b         }\cf1 {\b var}\cf3 {\b  handler = (}\cf5 {\b Action}\cf3 &amp;lt;TEvent&amp;gt;) handlers[\cf1 {\b typeof}\cf3 {\b  (TEvent)];}\par ??\par ??{\b         handler.Invoke(eventToDispatch);}\par ??{\b     \}}\par ??{\b \}}}&lt;br /&gt;--&gt;  &lt;div style="padding-bottom: 0.4em; line-height: 1.1em; padding-left: 0.4em; padding-right: 0.4em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.4em"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;ActionEventDispatcher&lt;/span&gt; : &lt;span style="color: #6897bb"&gt;IEventDispatcher&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="color: #cc7832"&gt;readonly&lt;/span&gt; &lt;span style="color: #6897bb"&gt;IDictionary&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;Type&lt;/span&gt;, &lt;span style="color: #ffc66d"&gt;Delegate&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt; handlers;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; ActionEventDispatcher()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; handlers = &lt;span style="color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;Dictionary&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;Type&lt;/span&gt;, &lt;span style="color: #ffc66d"&gt;Delegate&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;();&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; Register&amp;lt;TEvent&amp;gt;(&lt;span style="color: #6897bb"&gt;Action&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;TEvent&amp;gt; eventAction) &lt;/span&gt;&lt;span style="color: #cc7832"&gt;where&lt;/span&gt; TEvent : &lt;span style="color: #6897bb"&gt;IEvent&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: gray"&gt;// assuming you'll only register once per test&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; handlers.Add(&lt;span style="color: #cc7832"&gt;typeof&lt;/span&gt;(TEvent), eventAction);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; Dispatch&amp;lt;TEvent&amp;gt;(TEvent eventToDispatch) &lt;span style="color: #cc7832"&gt;where&lt;/span&gt; TEvent : &lt;span style="color: #6897bb"&gt;IEvent&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;if&lt;/span&gt; (!handlers.ContainsKey(&lt;span style="color: #cc7832"&gt;typeof&lt;/span&gt; (TEvent))) &lt;span style="color: #cc7832"&gt;return&lt;/span&gt;;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; handler = (&lt;span style="color: #6897bb"&gt;Action&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;TEvent&amp;gt;) handlers[&lt;/span&gt;&lt;span style="color: #cc7832"&gt;typeof&lt;/span&gt; (TEvent)];&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; handler.Invoke(eventToDispatch);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;You’ll notice that the two event dispatchers are the two sides that can be executed in Udi’s implementation. That is the essence of the &lt;a href="http://en.wikipedia.org/wiki/Strategy_pattern"&gt;strategy pattern&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;This does modify the test slightly so that you now have to do this:&lt;/p&gt; &lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red255\green255\blue255;\red39\green39\blue39;\red255\green198\blue109;\red204\green120\blue50;}??\fs20 \cf1\cb2\highlight2 {\b [}\cf3 {\b Test}\cf1 {\b ]}\par ??\cf4 {\b public}\cf1 {\b  }\cf4 {\b void}\cf1 {\b  DoSomethingShouldMakeCustomerPreferred()}\par ??{\b \{}\par ??{\b     }\cf4 {\b var}\cf1 {\b  c = }\cf4 {\b new}\cf1 {\b  }\cf3 {\b Customer}\cf1 {\b ();}\par ??{\b     }\cf3 {\b Customer}\cf1 {\b  preferred = }\cf4 {\b null}\cf1 {\b ;}\par ??\par ??{\b     }\cf4 {\b var}\cf1 {\b  eventDispatcher = }\cf4 {\b new}\cf1 {\b  }\cf3 {\b ActionEventDispatcher}\cf1 {\b ();}\par ??\par ??{\b     }\cf3 {\b DomainEvent}\cf1 .Dispatcher = eventDispatcher;\par ??\par ??{\b     eventDispatcher.Register&amp;lt;}\cf3 {\b CustomerBecamePreferred}\cf1 &amp;gt;\par ??{\b         (p =&amp;gt; preferred = p.Customer);}\par ??\par ??{\b     c.DoSomething();}\par ??{\b     Assert(preferred == c &amp;amp;&amp;amp; c.IsPreferred);}\par ??{\b \}}}&lt;br /&gt;--&gt;  &lt;div style="padding-bottom: 0.4em; line-height: 1.1em; padding-left: 0.4em; padding-right: 0.4em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.4em"&gt;   &lt;p style="margin: 0px"&gt;[&lt;span style="color: #ffc66d"&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; DoSomethingShouldMakeCustomerPreferred()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; c = &lt;span style="color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;Customer&lt;/span&gt;();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Customer&lt;/span&gt; preferred = &lt;span style="color: #cc7832"&gt;null&lt;/span&gt;;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; eventDispatcher = &lt;span style="color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;ActionEventDispatcher&lt;/span&gt;();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;DomainEvent&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Dispatcher = eventDispatcher;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; eventDispatcher.Register&amp;lt;&lt;span style="color: #ffc66d"&gt;CustomerBecamePreferred&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (p =&amp;gt; preferred = p.Customer);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; c.DoSomething();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; Assert(preferred == c &amp;amp;&amp;amp; c.IsPreferred);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;I would put the attachment of the ActionEventDispatcher into a test base class so that you didn’t have to set it up for every test, reducing the noise added.&lt;/p&gt;  &lt;p&gt;You would also have to add a small bit of code to hook up your real event dispatcher when your application started:&lt;/p&gt; &lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red204\green120\blue50;\red39\green39\blue39;\red255\green255\blue255;\red255\green198\blue109;}??\fs20 \cf1\cb2\highlight2 {\b public}\cf3 {\b  }\cf1 {\b void}\cf3 {\b  SetEventDispatcher()}\par ??{\b \{}\par ??{\b     }\cf4 {\b DomainEvent}\cf3 .Dispatcher = \cf1 {\b new}\cf3 {\b  }\cf4 {\b StructureMapEventDispatcher}\cf3 {\b ();}\par ??{\b \}}}&lt;br /&gt;--&gt;  &lt;div style="padding-bottom: 0.4em; line-height: 1.1em; padding-left: 0.4em; padding-right: 0.4em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.4em"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; SetEventDispatcher()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;{&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;DomainEvent&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Dispatcher = &lt;/span&gt;&lt;span style="color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;StructureMapEventDispatcher&lt;/span&gt;();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Still not sure whether I like the use of domain events or not. However, I did notice this potential refactoring whilst reading the article and thought it was interesting enough to blog about. I think it has left the code in a much better state and I think it also addresses some of the concerns that were raised about the static class at &lt;a href="http://altnetuk.com/"&gt;AltNetUK&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-3524433336717462490?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=oY9WOcNQ10E:e-g-BCmAAzA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=oY9WOcNQ10E:e-g-BCmAAzA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=oY9WOcNQ10E:e-g-BCmAAzA:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=oY9WOcNQ10E:e-g-BCmAAzA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=oY9WOcNQ10E:e-g-BCmAAzA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=oY9WOcNQ10E:e-g-BCmAAzA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=oY9WOcNQ10E:e-g-BCmAAzA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/oY9WOcNQ10E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/3524433336717462490/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=3524433336717462490" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3524433336717462490?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3524433336717462490?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/oY9WOcNQ10E/better-domain-event-raiser.html" title="A better domain event raiser" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/08/better-domain-event-raiser.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QHQHc6eyp7ImA9WxJbFUk.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-9056367122077205045</id><published>2009-07-25T20:15:00.001+01:00</published><updated>2009-07-25T20:15:31.913+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-25T20:15:31.913+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="REST" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC" /><title>POST overload – implementation considerations</title><content type="html">&lt;p&gt;As I have &lt;a href="http://blog.robustsoftware.co.uk/2009/07/rest-quick-summary.html"&gt;been&lt;/a&gt;&amp;#160;&lt;a href="http://blog.robustsoftware.co.uk/2009/07/restful-aspnet-mvc.html"&gt;blogging&lt;/a&gt;&amp;#160;&lt;a href="http://blog.robustsoftware.co.uk/2009/07/overloading-post-change-of-mind.html"&gt;about&lt;/a&gt;, I’ve been fighting with myself over the best way to implement POST overloading in &lt;a href="http://code.google.com/p/restful-aspmvc/"&gt;RESTful ASP.NET MVC&lt;/a&gt;. I’m still not happy that I have chosen the best implementation in using the URL to indicate the overload but I’m done with thinking about it for now. I’m going to record my and others thoughts about the pros and cons of each approach and move on to other functionality.&lt;/p&gt;  &lt;p&gt;The two main points around which the discussion revolves are transparency and adherence to the spirit of HTTP. A compromise has to be made on one of them, which you choose to compromise, I feel, is a personal decision.&lt;/p&gt;  &lt;p&gt;Using a hidden form value for overloading is transparent to the user, the URL the POST is made to does not change. My &lt;a href="http://blog.robustsoftware.co.uk/2009/07/overloading-post-change-of-mind.html"&gt;previous argument&lt;/a&gt; for needing to implement overloading for different content types is nonsense as you would never need to use POST overloading apart from when POSTing a form from a browser. All other calls will be able to use the correct HTTP verb directly.&lt;/p&gt;  &lt;p&gt;The URL overloading method, for me, remains closer to the spirit of HTTP. If the URL contains the overload you know how to handle the request purely from the head of the HTTP request. Using the form value method you need to check the body of the HTTP request to know what to do.&lt;/p&gt;  &lt;p&gt;Neither method is ideal, they both have their compromises and I can’t honestly say whether one is better than the other at the moment. Perhaps I’ll obtain some insight later that makes one clearly better than the other. However, I do know that at the moment I’m risking the wrath of &lt;a href="http://blog.scottbellware.com/"&gt;Scott Bellware&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://twitter.com/gshutler"&gt;@gshutler&lt;/a&gt; ultimately, i'm gonna come gunning for you if this hack-in-the-uri becomes convention in the late-to-the-game .net rest users :) &lt;a href="http://twitter.com/bellware/statuses/2828993797"&gt;Sat 25 Jul 01:20&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;If you find me in a ditch because everyone starts using the URL overload method, you have a prime suspect.&lt;/p&gt;  &lt;p&gt;I’d like to thank &lt;a href="http://twitter.com/bellware"&gt;Scott Bellware&lt;/a&gt; and &lt;a href="http://twitter.com/serialseb"&gt;Sebastien Lambla&lt;/a&gt; for taking the time to talk to me about this subject over the past couple of weeks on twitter, it’s greatly appreciated.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-9056367122077205045?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=kTd3zbfHRSE:41fIUyTUQCc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=kTd3zbfHRSE:41fIUyTUQCc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=kTd3zbfHRSE:41fIUyTUQCc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=kTd3zbfHRSE:41fIUyTUQCc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=kTd3zbfHRSE:41fIUyTUQCc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=kTd3zbfHRSE:41fIUyTUQCc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=kTd3zbfHRSE:41fIUyTUQCc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/kTd3zbfHRSE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/9056367122077205045/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=9056367122077205045" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/9056367122077205045?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/9056367122077205045?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/kTd3zbfHRSE/post-overload-implementation.html" title="POST overload – implementation considerations" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/07/post-overload-implementation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUCR3k9eCp7ImA9WxJbFkU.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-5217201963277999827</id><published>2009-07-24T21:52:00.005+01:00</published><updated>2009-07-27T09:11:06.760+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-27T09:11:06.760+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="REST" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC" /><title>Overloading POST – a change of mind</title><content type="html">&lt;p&gt;Today I made a fairly fundamental change in design of &lt;a href="http://code.google.com/p/restful-aspmvc/"&gt;RESTful ASP.NET MVC&lt;/a&gt; revolving around how I will be overloading post for HTML forms. &lt;/p&gt;  &lt;p&gt;Previously I was adding a hidden field to the form, which is how it is done by Rails:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre style="line-height: 1.1em"&gt;&amp;lt;form method="POST" action="/Users/2"&amp;gt;&lt;br /&gt;&amp;lt;input value="DELETE" type="hidden" name="_method" /&amp;gt;&lt;br /&gt;&amp;lt;input value="Delete" type="submit" /&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;/pre&gt; &lt;/blockquote&gt; &lt;p&gt;I was aware of &lt;a href="http://trac.caffeine-it.com/openrasta"&gt;OpenRasta's&lt;/a&gt; method of overloading post which is to append the overload to the URI:&lt;/p&gt; &lt;blockquote&gt;   &lt;pre style="line-height: 1.1em"&gt;&amp;lt;form method="POST" action="/Users/2!DELETE"&amp;gt;&lt;br /&gt;&amp;lt;input value="Delete" type="submit" /&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;/pre&gt; &lt;/blockquote&gt; &lt;p&gt;However, I didn’t like the way the overload was opaque to the user and thinking that the Rails guys must have thought about it a fair bit I initially went with the former method.&lt;/p&gt; &lt;p&gt;I ended up having a discussion with &lt;a href="http://twitter.com/serialseb"&gt;Sebastien Lambla&lt;/a&gt;, the developer of &lt;a href="http://trac.caffeine-it.com/openrasta"&gt;OpenRasta&lt;/a&gt;, about the two options and why he had chosen the second method over the first (I love twitter for this). To be honest, I came away from the discussion thinking there wasn’t much to chose between the two, it just being down to a matter of preference. However, I kept thinking about it, questioning my decision and whether it my choice really was better than the other option.&lt;/p&gt;  &lt;p&gt;&lt;strike&gt;I had a moment of clarity whilst playing golf. I realised that, potentially, I might have to write post overload mechanisms for multiple formats as clients could submit requests in a variety of formats (XML, JSON, form, etc). If the overload is contained within the URL then the overload is independent of the body’s content type, simplifying things considerably.&lt;/strike&gt;&lt;/p&gt; &lt;p&gt;Now I had a reason to change, I did so, changing &lt;a href="http://code.google.com/p/restful-aspmvc/"&gt;RESTful ASP.NET MVC’s&lt;/a&gt; method of overloading post to the URI mechanism. As it happens this tidied up the code a little as I no longer had to pass around the form collection, I could work purely off the routing values.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Related posts:&lt;/em&gt;&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/07/restful-aspnet-mvc.html"&gt;RESTful ASP.NET MVC&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/07/rest-quick-summary.html"&gt;REST - a quick summary&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;You should &lt;a href="http://feeds2.feedburner.com/RobustSoftware"&gt;subscribe to my feed to keep up with development of RESTful ASP.NET MVC.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;UPDATE&lt;/b&gt;&lt;/p&gt;&lt;p&gt;I have written a &lt;a href="http://blog.robustsoftware.co.uk/2009/07/post-overload-implementation.html"&gt;follow-up post about the implementation considerations for POST overload&lt;/a&gt; that I recommend reading as well.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-5217201963277999827?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=neGSm4yuB8A:1rs0GfjHVsQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=neGSm4yuB8A:1rs0GfjHVsQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=neGSm4yuB8A:1rs0GfjHVsQ:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=neGSm4yuB8A:1rs0GfjHVsQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=neGSm4yuB8A:1rs0GfjHVsQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=neGSm4yuB8A:1rs0GfjHVsQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=neGSm4yuB8A:1rs0GfjHVsQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/neGSm4yuB8A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/5217201963277999827/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=5217201963277999827" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/5217201963277999827?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/5217201963277999827?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/neGSm4yuB8A/overloading-post-change-of-mind.html" title="Overloading POST – a change of mind" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/07/overloading-post-change-of-mind.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEGSHg5eip7ImA9WxJUGUk.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-3798571875403165157</id><published>2009-07-18T21:21:00.001+01:00</published><updated>2009-07-18T21:23:49.622+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-18T21:23:49.622+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Extension methods" /><category scheme="http://www.blogger.com/atom/ns#" term="REST" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC" /><title>ASP.NET MVC Route Testing with HTTP Verbs</title><content type="html">&lt;p&gt;I’ve started &lt;a href="http://blog.robustsoftware.co.uk/2009/07/restful-aspnet-mvc.html"&gt;RESTful ASP.NET MVC&lt;/a&gt; from scratch and I am test-driving it. Writing code without tests is ok for proofs of concept but as I was planning on continually adding to the project I felt I had to start again and make sure everything was tested. As part of the process I was looking to test my routing rules. I used &lt;a href="http://haacked.com/archive/2007/12/17/testing-routes-in-asp.net-mvc.aspx"&gt;Phil Haack’s route testing helper&lt;/a&gt; as a starting point but I think I’ve customised it enough to warrant a post.&lt;/p&gt;  &lt;p&gt;The first thing I did was change his static method into an extension method. However, my routes were also dependant upon the HTTP verb used so I had to add that in on top. I also needed to check that a route wouldn’t be matched for the same reason as a URI which is valid for a GET may not be valid for a POST.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://code.google.com/p/restful-aspmvc/source/browse/branches/testdriven/code/RestfulMVC.Test/RouteTestHelper.cs?r=5"&gt;My route test helper&lt;/a&gt; and &lt;a href="http://code.google.com/p/restful-aspmvc/source/browse/branches/testdriven/code/RestfulMVC.Test/Routes/WhenRoutesHaveBeenRegistered.cs?r=5"&gt;an example of it in action&lt;/a&gt; from the test-driven branch of &lt;a href="http://code.google.com/p/restful-aspmvc/"&gt;restful-aspmvc&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Related posts&lt;/em&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/07/restful-aspnet-mvc.html"&gt;RESTful ASP.NET MVC&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/07/rest-quick-summary.html"&gt;REST - a quick summary&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-3798571875403165157?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Hv_i8HiR0yg:p2vjRRr2C88:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Hv_i8HiR0yg:p2vjRRr2C88:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Hv_i8HiR0yg:p2vjRRr2C88:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Hv_i8HiR0yg:p2vjRRr2C88:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Hv_i8HiR0yg:p2vjRRr2C88:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Hv_i8HiR0yg:p2vjRRr2C88:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Hv_i8HiR0yg:p2vjRRr2C88:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/Hv_i8HiR0yg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/3798571875403165157/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=3798571875403165157" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3798571875403165157?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3798571875403165157?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/Hv_i8HiR0yg/aspnet-mvc-route-testing-with-http.html" title="ASP.NET MVC Route Testing with HTTP Verbs" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/07/aspnet-mvc-route-testing-with-http.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMESXYzeCp7ImA9WxJUGE4.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-7211204304122845686</id><published>2009-07-17T13:11:00.001+01:00</published><updated>2009-07-17T13:23:28.880+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-17T13:23:28.880+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="REST" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC" /><title>RESTful ASP.NET MVC</title><content type="html">&lt;p&gt;This is the first in what could be a series of posts on how to modify the internals of ASP.NET MVC in order to make it work in a more RESTful manner. If you want to work with a RESTful web framework built on .NET today then I recommend using &lt;a href="http://trac.caffeine-it.com/openrasta"&gt;OpenRasta&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The reason I’m doing this is two-fold:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;I want to learn more about REST beyond &lt;a href="http://blog.robustsoftware.co.uk/2009/07/rest-quick-summary.html"&gt;the theory&lt;/a&gt; and I learn more by doing. &lt;/li&gt;&lt;li&gt;Sometimes it’s impossible to convince people to use an open source framework like &lt;a href="http://trac.caffeine-it.com/openrasta"&gt;OpenRasta&lt;/a&gt;, but customising stuff produced by Microsoft is much better received. I hope this will help other people write more RESTful sites whilst using Microsoft-based frameworks. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;All the code I will be referring to is available on the &lt;a href="http://code.google.com/p/restful-aspmvc/"&gt;restful-aspmvc project page&lt;/a&gt;. At the time of writing this the code was on &lt;a href="http://code.google.com/p/restful-aspmvc/source/browse/?r=3"&gt;revision 3&lt;/a&gt;, so if you are reading this later on there my be some inconsistencies.&lt;/p&gt;&lt;h4&gt;The inspiration&lt;/h4&gt;&lt;p&gt;I wanted to be able to use RESTful URLs like those available in Ruby on Rails. These work by selecting the controller action through the use of the URL &lt;strong&gt;and&lt;/strong&gt; the HTTP verb.&lt;/p&gt;&lt;pre&gt;GET /users/               UsersController.Index()&lt;/pre&gt;&lt;pre&gt;POST /users/              UsersController.Create()&lt;/pre&gt;&lt;pre&gt;GET /users/{id}           UsersController.Show(id)&lt;/pre&gt;&lt;pre&gt;PUT /users/{id}           UsersController.Update(id)&lt;/pre&gt;&lt;pre&gt;DELETE /users/{id}        UsersController.Destroy(id)&lt;/pre&gt;&lt;p&gt;I then wanted to allow you to create different views of the resources by specifying other actions that can only use the GET verb like so:&lt;/p&gt;&lt;pre&gt;GET /users/{action}       UsersController.{Action}()&lt;/pre&gt;&lt;pre&gt;GET /users/{id}/{action}  UsersController.{Action}(id)&lt;/pre&gt;&lt;h4&gt;The implementation&lt;/h4&gt;&lt;p&gt;The above routes are achieved through these route mappings: &lt;a href="http://code.google.com/p/restful-aspmvc/source/browse/trunk/RESTfulMVC/Global.asax.cs?r=3"&gt;listing on Google code&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The next problem was to map to the different actions according to the URL and the HTTP verb. As web browsers only support GET and POST this requires a technique known as overloading POST. I tried doing this in a couple of ways, firstly by including the required HTTP verb in the URL:&lt;/p&gt;&lt;blockquote&gt; &lt;pre&gt;/users/{id}?verb=DELETE&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;However, I found this quite ugly. As we are overloading POST, there will always be a form involved, therefore I’ve specified the required verb (where necessary) with a hidden form field:&lt;/p&gt;&lt;blockquote&gt; &lt;pre style="line-height: 1.1em"&gt;&amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;/Users/2&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;input value=&amp;quot;DELETE&amp;quot; type=&amp;quot;hidden&amp;quot; name=&amp;quot;_verb&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;p&amp;gt;        &lt;br /&gt;        &amp;lt;input value=&amp;quot;Delete&amp;quot; type=&amp;quot;submit&amp;quot; /&amp;gt;        &lt;br /&gt;    &amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;Now the verb is specified in the form, we have our URLs working we now need to act on this information. For that I have used a customer controller factory (&lt;a href="http://code.google.com/p/restful-aspmvc/source/browse/trunk/RESTfulMVC/RestfulControllerFactory.cs?r=3"&gt;Google code listing&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;There’s a fair bit of code to include directly into a blog post so I’ll explain the general flow to you and if you’re interested in the implementation you can have a look at the listing.&lt;/p&gt;&lt;ol&gt; &lt;li&gt;When the controller is created we use the default implementation to retrieve the controller and give it a custom action invoker to use. &lt;/li&gt;  &lt;li&gt;When the action is invoked we first check if the verb being used is a POST, if it is we check the form for an override. If one exists we change what we think the HTTP verb is to the one passed. &lt;/li&gt;  &lt;li&gt;If no specific action has been used (the default action is Index because of the routes we specified) then we use the HTTP verb and whether an id was specified to determine the actual action required. &lt;/li&gt;  &lt;li&gt;We use the default implementation to invoke the action required. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The &lt;a href="http://code.google.com/p/restful-aspmvc/source/browse/?r=3"&gt;full code listing&lt;/a&gt; includes a basic site which shows all the overrides being used along with a couple of common custom views (new and edit are commonly used to display forms to create and update resources).&lt;/p&gt;&lt;p&gt;This is the first step towards making ASP.NET MVC more RESTful. I welcome your comments and feedback, especially if there is something in particular you’d like me to implement in the future.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-7211204304122845686?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=N75mF0ZjCm0:ZHCh6T31ttw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=N75mF0ZjCm0:ZHCh6T31ttw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=N75mF0ZjCm0:ZHCh6T31ttw:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=N75mF0ZjCm0:ZHCh6T31ttw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=N75mF0ZjCm0:ZHCh6T31ttw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=N75mF0ZjCm0:ZHCh6T31ttw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=N75mF0ZjCm0:ZHCh6T31ttw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/N75mF0ZjCm0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/7211204304122845686/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=7211204304122845686" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/7211204304122845686?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/7211204304122845686?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/N75mF0ZjCm0/restful-aspnet-mvc.html" title="RESTful ASP.NET MVC" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/07/restful-aspnet-mvc.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0IGSH8-eyp7ImA9WxJUFE8.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-4446578865332214108</id><published>2009-07-12T19:28:00.001+01:00</published><updated>2009-07-12T21:12:09.153+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-12T21:12:09.153+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="REST" /><title>REST – a quick summary</title><content type="html">&lt;p&gt;I’d read a lot of blogs talking about REST and it’s benefits but I hadn’t fully got it. Whilst on holiday I read &lt;a href="http://www.amazon.co.uk/RESTful-Web-Services-Leonard-Richardson/dp/0596529260/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1247417574&amp;amp;sr=8-1"&gt;RESTful Web Services&lt;/a&gt;, which I had seen recommended, in an effort to try and finally grok REST. &lt;/p&gt;  &lt;p&gt;I thoroughly recommend this book, it helped me connect a lot of previously separate ideas into a coherent whole. What I hope to do here is give an overview of what I’ve learnt from the book to act as a reference to myself and maybe help other people in the process.&lt;/p&gt;  &lt;h4&gt;Definition&lt;/h4&gt;  &lt;p&gt;REST is short for &lt;strong&gt;Representational State Transfer&lt;/strong&gt;. Distilled down, it’s basically about using the &lt;strong&gt;HTTP verbs&lt;/strong&gt;, &lt;strong&gt;GET&lt;/strong&gt;, &lt;strong&gt;POST&lt;/strong&gt;, &lt;strong&gt;PUT&lt;/strong&gt;, &lt;strong&gt;DELETE&lt;/strong&gt; and &lt;strong&gt;HEAD&lt;/strong&gt;, in order to act on &lt;strong&gt;resources&lt;/strong&gt;, represented by individual URIs.&lt;/p&gt;  &lt;p&gt;Resources are &lt;em&gt;similar&lt;/em&gt; to what most of you will think of as domain entities. However, a relationship between two entities can be represented by a resource.&lt;/p&gt;  &lt;h4&gt;Underlying principle&lt;/h4&gt;  &lt;p&gt;The main idea behind REST is that you are working with the HTTP protocol. Other web service ideas like SOAP, referred to in the book as Big Web Services, mostly ignore the expressiveness of the HTTP protocol and use only GET and/or POST requests. This often works against the HTTP protocol, at best it ignores .&lt;/p&gt;  &lt;p&gt;The requests and responses of the HTTP protocol consist of a &lt;strong&gt;head&lt;/strong&gt; and a &lt;strong&gt;body&lt;/strong&gt;. The analogy used in the book is one of an envelope, the head being the envelope and the body being the contents of the envelope. REST uses the URI, HTTP verbs, HTTP headers and HTTP response codes in order to communicate to the server what is wanted and to the client what happened.&lt;/p&gt;  &lt;p&gt;This is in contrast to SOAP which generally uses the URI from the head and then sends another envelope in the body to communicate more information about the request to the server and the response to the client. This is effectively putting an envelope inside another envelope.&lt;/p&gt;  &lt;h4&gt;HTTP verbs and their meanings&lt;/h4&gt;  &lt;p&gt;The beauty of the verbs are that they are mostly self-explanatory, but I’ll explain all of them for completeness.&lt;/p&gt;  &lt;h5&gt;GET&lt;/h5&gt;  &lt;p&gt;This verb means give me the current representation for the given URI. You can use headers to modify the behaviour slightly. For example, the &lt;strong&gt;If-Modified-Since&lt;/strong&gt; header can be used to say “only send me the representation for the URI if it has changed since the given date”. This can be used to minimize needless traffic and processing.&lt;/p&gt;  &lt;h5&gt;DELETE&lt;/h5&gt;  &lt;p&gt;This verb means delete the representation at the given URI. There’s not really anything complicated about it.&lt;/p&gt;  &lt;h5&gt;HEAD&lt;/h5&gt;  &lt;p&gt;This is equivalent to a GET request but only returns the HEAD of the response, omitting the BODY. This is used for getting the meta data about a resource, for example checking whether a resource exists at a given URI without retrieving the BODY as well.&lt;/p&gt;  &lt;h5&gt;POST and PUT&lt;/h5&gt;  &lt;p&gt;I’ve put these two together as they are the ones I previously had most difficulty differentiating between. Needless to say the book explained the difference perfectly.&lt;/p&gt;  &lt;p&gt;PUT is used to place a resource to a &lt;em&gt;specific&lt;/em&gt; URI (eg. /Product/1), this can be a resource that didn’t exist before (an insert) or replace the existing representation at that URI (an update). In contrast, POST is used to add a resource to the end of a list of resources (eg. /Product) when you don’t know the URI in advance (an insert). Once you know the URI of your new resource, you will use a PUT to update it.&lt;/p&gt;  &lt;h4&gt;REST and HTML forms&lt;/h4&gt;  &lt;p&gt;A problem I had was reuse of web service code with web sites, HTML only supports the verbs GET and POST. I was concerned about having to maintain two sets of code for acting on the same resources. This can be overcome by using a concept called &lt;strong&gt;overloaded post&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;The idea behind it is really simple, you include the verb you want to use as a query string parameter and POST to that URI (eg. /Product/1?method=DELETE). Then using some simple server-side code you handle the request as the verb passed instead of as a POST.&lt;/p&gt;  &lt;h4&gt;Conclusion&lt;/h4&gt;  &lt;p&gt;I’ve covered the main concepts that helped me understand the big picture of REST. I really think it is the best way to write web services so that they can be easily consumed by other people. The emphasis of REST is on simplicity, utilising the power of the HTTP protocol rather than building a new protocol on top of it. This goes against the common practice up until this point, which to me is a breath of fresh air.&lt;/p&gt;  &lt;p&gt;Finally, I strongly recommend you buy &lt;a href="http://www.amazon.co.uk/RESTful-Web-Services-Leonard-Richardson/dp/0596529260/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1247417574&amp;amp;sr=8-1"&gt;the book&lt;/a&gt; if you are interested in learning more about REST.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-4446578865332214108?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=cWajBYqCYR4:IMQ1I90MAMc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=cWajBYqCYR4:IMQ1I90MAMc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=cWajBYqCYR4:IMQ1I90MAMc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=cWajBYqCYR4:IMQ1I90MAMc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=cWajBYqCYR4:IMQ1I90MAMc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=cWajBYqCYR4:IMQ1I90MAMc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=cWajBYqCYR4:IMQ1I90MAMc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/cWajBYqCYR4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/4446578865332214108/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=4446578865332214108" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/4446578865332214108?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/4446578865332214108?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/cWajBYqCYR4/rest-quick-summary.html" title="REST – a quick summary" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/07/rest-quick-summary.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIGRHYzfSp7ImA9WxJUEkk.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-9060546616244980864</id><published>2009-07-10T18:55:00.001+01:00</published><updated>2009-07-10T18:55:25.885+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-10T18:55:25.885+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Community" /><title>Nott Tuesday and the altnetbeers format</title><content type="html">&lt;p&gt;As &lt;a href="http://blog.robustsoftware.co.uk/2009/06/nott-tuesday-july-14th.html"&gt;I said previously&lt;/a&gt; I’ve volunteered to lead this month’s &lt;a href="http://notttuesday.com/"&gt;Nott Tuesday&lt;/a&gt; event, taking place this coming Tuesday, 14th July.&lt;/p&gt;  &lt;p&gt;So, as promised, I’m going to give the outline of how the whole evening will work. Hopefully it will encourage more participation from the whole group in the discussion, improving the night for everyone.&lt;/p&gt;  &lt;h4&gt;Topic selection&lt;/h4&gt;  &lt;p&gt;So a little while after 18:30, once everyone has had the chance to say hellos and so forth, I’ll ask everyone to volunteer topics for discussion. I’ll provide a stack of index cards and pens and anyone who has something they’d like to talk about can write a question on a card and put it onto a table for others to see. Something as vague as “why agile?” or specific as “how do I leverage e-marketing to obtain new business?” is fine. Framing it as a question will probably work better, but if you can’t do that then a simple sentence will do. The idea is to give the group a starting point for a discussion.&lt;/p&gt;  &lt;p&gt;Once we’ve had 5-10 minutes to write down our ideas we will whittle them down to the few most popular topics by voting on the ideas as a group. We’ll start off with the most popular topic and if the discussion is lively enough for long enough that might be all we discuss all night but if things start tailing off we’ll move on to the next most popular topic.&lt;/p&gt;  &lt;h4&gt;How does the discussion work?&lt;/h4&gt;  &lt;p&gt;There will be a “bench” where 3 people sit, they are the panel of which the group can ask questions. To begin with I’ll ask whichever person raised the topic to speak for 30 seconds or so just to explain a bit further what they want to get from the discussion. This person will also start off on the bench along with 2 volunteers. It is then thrown to the floor to ask questions of the bench. If you have a question, raise your hand and I’ll pick a person at a time to ask their question to stop it being a free-for-all. If you are part of the audience, you can only ask questions or come back on the answers given by the panel when applicable. &lt;/p&gt;  &lt;p&gt;If it is a topic you are interested in and have something to say about it, you can go and sit in the “hot seat”, this signifies you want to be on the bench and answer questions. When someone is in the hot seat, someone from the bench is obliged to return to the audience, allowing the person in the hot seat to move onto the bench. This can manage itself by people not having more to say or wanting a break, but if not we’ll do it on a first-in-first-out basis.&lt;/p&gt;  &lt;h4&gt;A personal plea&lt;/h4&gt;  &lt;p&gt;Please be gentle with me, it’s the first time I’ve run something like this so bear with me a bit. I might need to cut you off if you’re in the middle of a heated discussion but the majority of the room looks bored, please bear in mind I’m trying to keep it interesting for the whole group. There’s nothing to stop your carrying on the discussion afterwards of course!&lt;/p&gt;  &lt;p&gt;That’s all there is to it really. Hopefully, it will result in an enjoyable evening for everyone, having lively discussions about topics we’re all interested in.&lt;/p&gt;  &lt;p&gt;See you at &lt;a href="http://maps.google.co.uk/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=5+Broadway,+Nottingham,+NG1+1PR&amp;amp;sll=52.951968,-1.143397&amp;amp;sspn=0.008507,0.017273&amp;amp;gl=uk&amp;amp;ie=UTF8&amp;amp;z=16&amp;amp;iwloc=A"&gt;Bluu&lt;/a&gt; on Tuesday 14th July at 18:30!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-9060546616244980864?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=5ZJDZGfNBX4:cSltcWZiwwU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=5ZJDZGfNBX4:cSltcWZiwwU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=5ZJDZGfNBX4:cSltcWZiwwU:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=5ZJDZGfNBX4:cSltcWZiwwU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=5ZJDZGfNBX4:cSltcWZiwwU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=5ZJDZGfNBX4:cSltcWZiwwU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=5ZJDZGfNBX4:cSltcWZiwwU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/5ZJDZGfNBX4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/9060546616244980864/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=9060546616244980864" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/9060546616244980864?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/9060546616244980864?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/5ZJDZGfNBX4/nott-tuesday-and-altnetbeers-format.html" title="Nott Tuesday and the altnetbeers format" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/07/nott-tuesday-and-altnetbeers-format.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0cDQ3k_eyp7ImA9WxJWGU4.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-4833588362135594986</id><published>2009-06-25T12:57:00.001+01:00</published><updated>2009-06-25T12:57:52.743+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-25T12:57:52.743+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="notttuesday" /><category scheme="http://www.blogger.com/atom/ns#" term="Community" /><title>Nott Tuesday – July 14th</title><content type="html">&lt;p&gt;So I went to &lt;a href="http://notttuesday.com/"&gt;Nott Tuesday&lt;/a&gt; for the first time last month and really enjoyed it. &lt;a href="http://twitter.com/adambird"&gt;Adam Bird&lt;/a&gt;, the guy who started it up seemed keen to move towards group discussion rather than one or two people presenting to the group.&lt;/p&gt;  &lt;p&gt;I’d been to a similar event before, &lt;a href="http://ukdotnet.ning.com/events/london-altnetbeers-8"&gt;altnetbeers&lt;/a&gt;, which is run by &lt;a href="http://twitter.com/serialseb"&gt;Sebastien Lambla&lt;/a&gt; in London. Altnetbeers had the sort of group discussion I felt Adam was looking for so I dropped him an email the next day explaining the format to see what he though.&lt;/p&gt;  &lt;p&gt;Well I should have known better because, as &lt;a href="http://notttuesday.com/2009/06/25/tuesday-july-14th-something-a-little-different/"&gt;has now been announced&lt;/a&gt;, Adam said he liked the sound of it and asked me if I wanted to lead the next meeting in the style of altnetbeers. I couldn’t well say no after telling him how great it was so here we are.&lt;/p&gt;  &lt;p&gt;I’ll be cross posting an explanation of how it all works a bit nearer the time so that people will have an idea of what will be happening on the night.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-4833588362135594986?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=M_JYUqU7IGQ:7kso2h8-HIE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=M_JYUqU7IGQ:7kso2h8-HIE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=M_JYUqU7IGQ:7kso2h8-HIE:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=M_JYUqU7IGQ:7kso2h8-HIE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=M_JYUqU7IGQ:7kso2h8-HIE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=M_JYUqU7IGQ:7kso2h8-HIE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=M_JYUqU7IGQ:7kso2h8-HIE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/M_JYUqU7IGQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/4833588362135594986/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=4833588362135594986" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/4833588362135594986?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/4833588362135594986?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/M_JYUqU7IGQ/nott-tuesday-july-14th.html" title="Nott Tuesday – July 14th" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/06/nott-tuesday-july-14th.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0ECQ30zeyp7ImA9WxJWEk4.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-3050076459776338295</id><published>2009-06-17T12:54:00.001+01:00</published><updated>2009-06-17T12:54:22.383+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-17T12:54:22.383+01:00</app:edited><title>Opening a Command Prompt for the solution in Visual Studio</title><content type="html">&lt;p&gt;Something I’ve found myself needing to do more recently is open a command prompt at the root directory of my solution. Often this is to run a rake task or something like that.&lt;/p&gt;  &lt;p&gt;The way I used to do this was rather long winded, but now I’ve got it down to a single key combination and I’ll explain here how you can do the same.&lt;/p&gt;  &lt;p&gt;Firstly, open up the external tools dialog in Visual Studio:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="externaltools_menu" border="0" alt="externaltools_menu" src="http://lh3.ggpht.com/_GAonj6z3iqg/SjjZXHNyxlI/AAAAAAAAACM/3Vi790QDVSk/externaltools_menu%5B6%5D.png?imgmax=800" width="536" height="747" /&gt;&lt;/p&gt;  &lt;p&gt;Then add a new tool:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="externaltools_add" border="0" alt="externaltools_add" src="http://lh4.ggpht.com/_GAonj6z3iqg/SjjZXlxVqgI/AAAAAAAAACQ/KrdV1TiZ7WE/externaltools_add%5B5%5D.png?imgmax=800" width="465" height="452" /&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;This will give you a prompt to type the details of the new tool into:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="externaltools_adddialog" border="0" alt="externaltools_adddialog" src="http://lh5.ggpht.com/_GAonj6z3iqg/SjjZX0aFJqI/AAAAAAAAACU/6VO1WzuWXKo/externaltools_adddialog%5B2%5D.png?imgmax=800" width="465" height="452" /&gt; &lt;/p&gt;  &lt;p&gt;Then fill in the details of the new tool. We want to point this at cmd.exe which is usually located in your System32 directory. You also want to set the initial directory to the solution directory: &lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="externaltools_solution" border="0" alt="externaltools_solution" src="http://lh3.ggpht.com/_GAonj6z3iqg/SjjZYVhh10I/AAAAAAAAACY/AvDa0S37jfc/externaltools_solution%5B2%5D.png?imgmax=800" width="724" height="551" /&gt; &lt;/p&gt;  &lt;p&gt;I have then moved the tool up the list just because I like it being higher. The position of the tool in the list only makes a difference when setting up a keyboard shortcut as I will explain in a minute:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="externaltools_moveup" border="0" alt="externaltools_moveup" src="http://lh5.ggpht.com/_GAonj6z3iqg/SjjZY0IRl9I/AAAAAAAAACc/kQNUxFvHUbo/externaltools_moveup%5B5%5D.png?imgmax=800" width="465" height="452" /&gt; &lt;/p&gt;  &lt;p&gt;Once you’ve filled in all the details and moved the tool to the position you want it in just click Ok. You will now see that the tool you just created appears in the external tools section of the tools menu:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="externaltool_in_menu" border="0" alt="externaltool_in_menu" src="http://lh4.ggpht.com/_GAonj6z3iqg/SjjZZYRSxCI/AAAAAAAAACg/Dps8keGEZm0/externaltool_in_menu%5B2%5D.png?imgmax=800" width="492" height="749" /&gt;&lt;/p&gt;  &lt;p&gt;Now we can set up a keyboard shortcut for the new tool. Firstly, open the options dialog:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="tools_options" border="0" alt="tools_options" src="http://lh3.ggpht.com/_GAonj6z3iqg/SjjZZwYLWYI/AAAAAAAAACk/qCXs0707s64/tools_options%5B2%5D.png?imgmax=800" width="486" height="735" /&gt; &lt;/p&gt;  &lt;p&gt;Then go to the keyboard section:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="options_keyboard" border="0" alt="options_keyboard" src="http://lh3.ggpht.com/_GAonj6z3iqg/SjjZaXMFz2I/AAAAAAAAACo/sf54FbJ2h80/options_keyboard%5B2%5D.png?imgmax=800" width="751" height="432" /&gt; &lt;/p&gt;  &lt;p&gt;Then type in the command name “Tools.ExternalCommandX” where X is the number your tool appears in the list. Mine is second so I type “2”:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="tools_keyboard_externalcommand2" border="0" alt="tools_keyboard_externalcommand2" src="http://lh3.ggpht.com/_GAonj6z3iqg/SjjZa49P8MI/AAAAAAAAACs/B2-E5NTnJh4/tools_keyboard_externalcommand2%5B2%5D.png?imgmax=800" width="751" height="432" /&gt; &lt;/p&gt;  &lt;p&gt;Then assign a key combination to this command. I chose Ctrl+Shift+Alt+C:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="tools_keyboard_assign" border="0" alt="tools_keyboard_assign" src="http://lh6.ggpht.com/_GAonj6z3iqg/SjjZbWmoU-I/AAAAAAAAACw/sWotLdz5xw8/tools_keyboard_assign%5B2%5D.png?imgmax=800" width="751" height="432" /&gt; &lt;/p&gt;  &lt;p&gt;Then click ok and you will now be able to open a command prompt at the root of the current solution with your key combination.&lt;/p&gt;  &lt;p&gt;This principle can be extended to call any program, you may have noticed I use it to call the default rake task for my solution.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-3050076459776338295?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=sYXxkPVrGgU:VWbJ0m00Bdc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=sYXxkPVrGgU:VWbJ0m00Bdc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=sYXxkPVrGgU:VWbJ0m00Bdc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=sYXxkPVrGgU:VWbJ0m00Bdc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=sYXxkPVrGgU:VWbJ0m00Bdc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=sYXxkPVrGgU:VWbJ0m00Bdc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=sYXxkPVrGgU:VWbJ0m00Bdc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/sYXxkPVrGgU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/3050076459776338295/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=3050076459776338295" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3050076459776338295?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3050076459776338295?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/sYXxkPVrGgU/opening-command-prompt-for-solution-in.html" title="Opening a Command Prompt for the solution in Visual Studio" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/06/opening-command-prompt-for-solution-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEAERn8-eSp7ImA9WxJRE0Q.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-2879189448286727930</id><published>2009-05-15T14:05:00.001+01:00</published><updated>2009-05-15T14:05:07.151+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-15T14:05:07.151+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Community" /><title>Establishing Team Values</title><content type="html">&lt;p&gt;One of the biggest things I took from the Progressive .NET tutorials was the idea of establishing a set of values for your team.&lt;/p&gt;  &lt;p&gt;This was raised in &lt;a href="http://codebetter.com/blogs/david_laribee/"&gt;David Laribee’s&lt;/a&gt; session &lt;a href="http://skillsmatter.com/podcast/open-source-dot-net/towards-a-new-architect"&gt;Towards A New Architect&lt;/a&gt; (watch out for the video of that coming out) where he asked whose team had a set of common values. In a room of 30 or so people, I think 3 or 4 raised their hand.&lt;/p&gt;  &lt;p&gt;As soon as it was mentioned it made sense to me. A shared identity and core set of values can only benefit a team. To that end I’m going to run a similar session to the one I participated in in order to establish a set of values for my team.&lt;/p&gt;  &lt;p&gt;I thought I might share the format I’m going to use so that others might do the same:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Set up a 1 hour session for discovering your team’s values &lt;/strong&gt;&lt;/p&gt;  &lt;p style="margin-bottom: 0px"&gt;5 minutes explaining what we are doing and what we want to achieve&lt;/p&gt;  &lt;ul style="margin-top: 0px"&gt;   &lt;li&gt;bring common values to the fore &lt;/li&gt;    &lt;li&gt;give a common identity to the team &lt;/li&gt;    &lt;li&gt;create a catalyst for improvement &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;DIVERGE, CONVERGE, SYNTHESIZE&lt;/strong&gt; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;5 minutes writing words or short phrases down &lt;/li&gt;    &lt;li&gt;5 minutes converging to write all the different phrases on the board by going round the group &lt;/li&gt;    &lt;li&gt;2 minutes dot voting &lt;/li&gt;    &lt;li&gt;1 minute selecting top 3-5 by votes &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;DIVERGE, CONVERGE, SYNTHESIZE&lt;/strong&gt; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;10 minutes to write a sentence explaining why each phrase is important (each person doesn't have to do each one) &lt;/li&gt;    &lt;li&gt;10 minutes coming together, taking each word in turn and sharing sentences all written on the board &lt;/li&gt;    &lt;li&gt;2 minutes tweaking and eliminating duplicates &lt;/li&gt;    &lt;li&gt;2 minutes dot voting each group of sentences &lt;/li&gt;    &lt;li&gt;select the favourite sentence for each phrase&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Your team now has a set of common values &lt;/p&gt;  &lt;p&gt;Thank the team and tell them you are going to get them printed to put up on the wall. The important thing is that they are visible and prominent. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Important points&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;the number of values should be low – the messages should be simple and strong&lt;/li&gt;    &lt;li&gt;the values should be visible to the whole team, all the time&lt;/li&gt;    &lt;li&gt;everyone should be empowered to act to strengthen the values&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I’ll blog about what values my team at &lt;a href="http://www.openprojects.co.uk/"&gt;Open Projects&lt;/a&gt; have chosen next week.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-2879189448286727930?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=s1Lr66_OtoQ:FeMikyXq5gc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=s1Lr66_OtoQ:FeMikyXq5gc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=s1Lr66_OtoQ:FeMikyXq5gc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=s1Lr66_OtoQ:FeMikyXq5gc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=s1Lr66_OtoQ:FeMikyXq5gc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=s1Lr66_OtoQ:FeMikyXq5gc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=s1Lr66_OtoQ:FeMikyXq5gc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/s1Lr66_OtoQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/2879189448286727930/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=2879189448286727930" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/2879189448286727930?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/2879189448286727930?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/s1Lr66_OtoQ/establishing-team-values.html" title="Establishing Team Values" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/05/establishing-team-values.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcGQH08cSp7ImA9WxJREkQ.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-3252730160782739063</id><published>2009-05-14T11:46:00.000+01:00</published><updated>2009-05-14T11:47:01.379+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-14T11:47:01.379+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Replication" /><title>Great replication troubleshooting article</title><content type="html">&lt;p&gt;I found &lt;a href="http://www.sqlservercentral.com/articles/Replication/61891/"&gt;this article on troubleshooting replication woes&lt;/a&gt;, unfortunately it requires you to sign up for SQL Server Central. However, if you have the “pleasure” of dealing with replication it gives a lot of good pointers on sorting out problems so it’s worth it.&lt;/p&gt;  &lt;p style="margin-bottom: 0px"&gt;&lt;em&gt;Related posts:&lt;/em&gt;&lt;/p&gt;  &lt;ul style="margin-top: 0px"&gt;   &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/04/sql-server-2005-replication-errors.html"&gt;SQL Server 2005 replication errors table&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-3252730160782739063?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=52Ta3asPL0Y:RZzijwPvrwA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=52Ta3asPL0Y:RZzijwPvrwA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=52Ta3asPL0Y:RZzijwPvrwA:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=52Ta3asPL0Y:RZzijwPvrwA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=52Ta3asPL0Y:RZzijwPvrwA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=52Ta3asPL0Y:RZzijwPvrwA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=52Ta3asPL0Y:RZzijwPvrwA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/52Ta3asPL0Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/3252730160782739063/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=3252730160782739063" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3252730160782739063?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3252730160782739063?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/52Ta3asPL0Y/great-replication-troubleshooting.html" title="Great replication troubleshooting article" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/05/great-replication-troubleshooting.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYHQ344fCp7ImA9WxJREkQ.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-7435359942004868459</id><published>2009-05-14T09:35:00.001+01:00</published><updated>2009-05-14T09:35:32.034+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-14T09:35:32.034+01:00</app:edited><title>When geek rockstars go wild</title><content type="html">&lt;p&gt;Ok, a silly one but I’ve got to share this. When walking to the hotel on Sunday before Progressive .NET I saw this in &lt;a href="http://maps.google.co.uk/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=A201%2FActon+St&amp;amp;sll=51.528017,-0.117159&amp;amp;sspn=0.005273,0.009313&amp;amp;ie=UTF8&amp;amp;ll=51.528557,-0.117352&amp;amp;spn=0.010546,0.018625&amp;amp;z=16&amp;amp;iwloc=A"&gt;the middle of the pavement&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_GAonj6z3iqg/SgvX0FHVjPI/AAAAAAAAACE/oB1usgwbeEA/s1600-h/photo%5B12%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="smashed monitor" border="0" alt="smashed monitor" src="http://lh5.ggpht.com/_GAonj6z3iqg/SgvX02g6igI/AAAAAAAAACI/GPmXWTv2Mk0/photo_thumb%5B10%5D.jpg?imgmax=800" width="380" height="500" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I’m guessing someone broke the build and this is what happened to their monitor.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-7435359942004868459?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Buga-QWBtd4:TDfCsLvHHNw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Buga-QWBtd4:TDfCsLvHHNw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Buga-QWBtd4:TDfCsLvHHNw:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Buga-QWBtd4:TDfCsLvHHNw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Buga-QWBtd4:TDfCsLvHHNw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Buga-QWBtd4:TDfCsLvHHNw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Buga-QWBtd4:TDfCsLvHHNw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/Buga-QWBtd4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/7435359942004868459/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=7435359942004868459" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/7435359942004868459?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/7435359942004868459?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/Buga-QWBtd4/when-geek-rockstars-go-wild.html" title="When geek rockstars go wild" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/05/when-geek-rockstars-go-wild.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQFQHY7fyp7ImA9WxJSGEQ.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-3661595485405296346</id><published>2009-05-09T19:21:00.001+01:00</published><updated>2009-05-09T19:21:51.807+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-09T19:21:51.807+01:00</app:edited><title>Progressive .NET Tutorials</title><content type="html">&lt;p&gt;I will be attending &lt;a href="http://skillsmatter.com/event/open-source-dot-net/progressive-dot-net-exchange"&gt;the Progressive .NET Tutorials&lt;/a&gt; next week and I must say I’m looking forward to it. It’s slightly disappointing that &lt;a href="http://blog.scottbellware.com/"&gt;Scott Bellware&lt;/a&gt; couldn’t make it for his testing track on Monday but there’s plenty of other things going on. This is my plan for the week:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Sunday&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Travelling down from Nottingham with &lt;a href="http://www.muonlab.com/"&gt;Andrew Bullock&lt;/a&gt; and checking into the Farringdon Travelodge down the road from &lt;a href="http://skillsmatter.com/"&gt;Skills Matter&lt;/a&gt;. Nothing planned for this evening, probably get something to eat and then hit the hay before a busy few days.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Monday&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Going to start the morning with &lt;a href="http://skillsmatter.com/podcast/open-source-dot-net/good-test-better-code"&gt;Specification by example and Agile acceptance testing&lt;/a&gt; led by &lt;a href="http://gojko.net/"&gt;Gojko Adzic&lt;/a&gt;, it will be good to hear someone talk about testing as everything I’ve learnt has been picked up through screencasts and blogs.&lt;/p&gt;  &lt;p&gt;For the afternoon I’m uncertain whether to go for Gojko’s &lt;a href="http://skillsmatter.com/podcast/open-source-dot-net/web-testing-for-developers-with-application-models"&gt;FitNess.NET workshop&lt;/a&gt; or &lt;a href="http://serialseb.blogspot.com"&gt;Sebastien Lambla’s&lt;/a&gt; &lt;a href="http://skillsmatter.com/podcast/open-source-dot-net/openrasta-an-mvc-framework-with-strong-opinions"&gt;workshop on OpenRasta&lt;/a&gt;. I think how well I get on with Gojko’s style of presentation in the morning will be the deciding factor.&lt;/p&gt;  &lt;p&gt;In the evening I’m attempting to arrange &lt;a href="http://ukdotnet.ning.com/events/progressive-net-dinner"&gt;a meal&lt;/a&gt; with other people from the tutorials then probably go to a bar for a drink or two.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Tuesday&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I’m going to spend the whole day with &lt;a href="http://ayende.com/"&gt;Oren Eini&lt;/a&gt; learning about &lt;a href="https://www.hibernate.org/343.html"&gt;NHibernate&lt;/a&gt;. Again this is something I’m using already but all I’ve learnt is taken from the internet. Learning from one of the developers of NHibernate is an opportunity that cannot be missed.&lt;/p&gt;  &lt;p&gt;In the evening Sebastien Lambla has arranged &lt;a href="http://ukdotnet.ning.com/events/london-altnetbeers-8"&gt;AltNetBeers&lt;/a&gt; where there will be an OpenConf style discussion. I’m looking forward to this nearly as much as the tutorials themselves.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Wednesday&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Going to spend this day listening to &lt;a href="http://codebetter.com/blogs/david_laribee/"&gt;David Laribee's&lt;/a&gt; thoughts on project management and teamwork. I’m hoping to come away from this with inspiration on how I can help improve my team’s practices.&lt;/p&gt;  &lt;p&gt;Finishing it all off Skills Matter have arranged a trip to a pub for a drink or two. I’ll be spending about an hour there before catching the train back to Nottingham.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Thursday and Friday&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I’m planning on blogging about the things I’ve learnt over the previous 3 days. So look forward to a raft of blog posts.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;I might get chance to knock together a blog post, but I’ll be tweeting whenever I get half a second spare so &lt;a href="http://twitter.com/gshutler"&gt;follow me&lt;/a&gt; if you’re interested in what’s going on.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-3661595485405296346?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=whimeULDRu8:QG_Kn_nBllQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=whimeULDRu8:QG_Kn_nBllQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=whimeULDRu8:QG_Kn_nBllQ:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=whimeULDRu8:QG_Kn_nBllQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=whimeULDRu8:QG_Kn_nBllQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=whimeULDRu8:QG_Kn_nBllQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=whimeULDRu8:QG_Kn_nBllQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/whimeULDRu8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/3661595485405296346/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=3661595485405296346" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3661595485405296346?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3661595485405296346?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/whimeULDRu8/progressive-net-tutorials.html" title="Progressive .NET Tutorials" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/05/progressive-net-tutorials.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMCR3o_fyp7ImA9WxJSGEo.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-4384397612515431936</id><published>2009-05-09T14:57:00.001+01:00</published><updated>2009-05-09T14:57:46.447+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-09T14:57:46.447+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Extension methods" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><title>RhinoMocks IQueryable&lt;T&gt; helper</title><content type="html">&lt;p&gt;After reading &lt;a href="http://www.codebucket.org/archive/2009/05/07/using-nhibernate-to-test-your-query-logic-without-touching-the.aspx" target="_blank"&gt;Lee Brandt's post&lt;/a&gt; about how my answer to &lt;a href="http://stackoverflow.com/questions/448405/nhibernate-testing-mocking-isession" target="_blank"&gt;his question on Stack Overflow&lt;/a&gt; helped with testing the logic of his queries I realised that people might find one of my test helper extension methods useful.&lt;/p&gt;  &lt;p&gt;I found that in my tests I had to mock out the Query&amp;lt;T&amp;gt; function quite a lot which would look something like this:&lt;/p&gt;  &lt;div style="font-weight: bold; font-size: 10pt; background: #272727; padding-bottom: 0.6em; color: white; line-height: 1.2em; padding-top: 0.6em; font-family: consolas"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; EstablishContext()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; projects = &lt;span style="color: #cc7832"&gt;new&lt;/span&gt;[]&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Build&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Project().WithName(&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;AAAAAAA&amp;quot;&lt;/span&gt;).Create(),&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Build&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Project().WithName(&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;CCCCCCC&amp;quot;&lt;/span&gt;).Create(),&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Build&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Project().WithName(&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;BBBBBBB&amp;quot;&lt;/span&gt;).Create()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; };&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Mock&amp;lt;&lt;span style="color: #6897bb"&gt;IUnitOfWork&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;()&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Stub(x =&amp;gt; x.Query&amp;lt;&lt;span style="color: #ffc66d"&gt;Project&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;())&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Return(projects.AsQueryable());&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This was adding quite a lot of noise to my tests. I like to keep my tests as clean as possible to make them easier to scan when you need to review and understand them. Because of this I wanted to simplify the stubbing so there was as little code as possible. &lt;/p&gt;  &lt;p&gt;This was made possible by this simple extension method:&lt;/p&gt;  &lt;div style="font-weight: bold; font-size: 10pt; background: #272727; padding-bottom: 0.6em; color: white; line-height: 1.2em; padding-top: 0.6em; font-family: consolas"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;static&lt;/span&gt; &lt;span style="color: #6897bb"&gt;IMethodOptions&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #6897bb"&gt;IQueryable&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;TEntity&amp;gt;&amp;gt; ReturnQueryable&amp;lt;TEntity&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (&lt;span style="color: #cc7832"&gt;this&lt;/span&gt; &lt;span style="color: #6897bb"&gt;IMethodOptions&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #6897bb"&gt;IQueryable&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;lt;TEntity&amp;gt;&amp;gt; options, &lt;/span&gt;&lt;span style="color: #cc7832"&gt;params&lt;/span&gt; TEntity[] items)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;return&lt;/span&gt; options.Return(items.AsQueryable());&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;The magic sauce in this is the items parameter. I’ve used the params modifier so that I can provide any number of TEntity objects for the IQueryable function to return.&lt;/p&gt;  &lt;p&gt;This tidies the above setup code down to this:&lt;/p&gt;  &lt;div style="font-weight: bold; font-size: 10pt; background: #272727; padding-bottom: 0.6em; color: white; line-height: 1.2em; padding-top: 0.6em; font-family: consolas"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color: #cc7832"&gt;protected&lt;/span&gt; &lt;span style="color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; EstablishContext()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Mock&amp;lt;&lt;span style="color: #6897bb"&gt;IUnitOfWork&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;()&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Stub(x =&amp;gt; x.Query&amp;lt;&lt;span style="color: #ffc66d"&gt;Project&lt;/span&gt;&lt;span style="font-weight: normal"&gt;&amp;gt;())&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .ReturnQueryable(&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Build&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Project().WithName(&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;AAAAAAA&amp;quot;&lt;/span&gt;).Create(), &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Build&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Project().WithName(&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;CCCCCCC&amp;quot;&lt;/span&gt;).Create(),&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Build&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Project().WithName(&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;BBBBBBB&amp;quot;&lt;/span&gt;).Create()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; );&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: normal; color: #2b91af"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;I find this much cleaner and easier to read, hope this helps someone out.&lt;/p&gt;  &lt;p&gt;Happy testing!&lt;/p&gt;  &lt;p style="margin-bottom: 0px"&gt;&lt;em&gt;Related posts:&lt;/em&gt;&lt;/p&gt;  &lt;ul style="margin-top: 0px"&gt;   &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/02/test-aided-development.html"&gt;Test aided development&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/05/difference-between-areequal-and-aresame.html"&gt;Difference between AreEqual and AreSame&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2008/01/more-fluent-assertions-using-extension.html"&gt;More fluent assertions using extension methods&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-4384397612515431936?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bVxQHCU7HUw:CZEhi3vgnpE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=bVxQHCU7HUw:CZEhi3vgnpE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bVxQHCU7HUw:CZEhi3vgnpE:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bVxQHCU7HUw:CZEhi3vgnpE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=bVxQHCU7HUw:CZEhi3vgnpE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bVxQHCU7HUw:CZEhi3vgnpE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=bVxQHCU7HUw:CZEhi3vgnpE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/bVxQHCU7HUw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/4384397612515431936/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=4384397612515431936" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/4384397612515431936?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/4384397612515431936?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/bVxQHCU7HUw/rhinomocks-iqueryable-helper.html" title="RhinoMocks IQueryable&amp;lt;T&amp;gt; helper" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/05/rhinomocks-iqueryable-helper.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEcFRH46eyp7ImA9WxJSF0U.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-6926690411661343781</id><published>2009-05-08T13:17:00.001+01:00</published><updated>2009-05-08T13:33:35.013+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-08T13:33:35.013+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Community" /><title>A new name for ALT.NET</title><content type="html">&lt;p&gt;I will be attending &lt;a href="http://progressive-dotnet.com/"&gt;Progressive .NET Tutorials&lt;/a&gt; next week and it got me thinking this morning.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Wouldn’t Progressive .NET be a much more &lt;strong&gt;positive&lt;/strong&gt; and &lt;strong&gt;inclusionary&lt;/strong&gt; name?&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I’ve always felt the alternative part of ALT.NET to be quite elitist, exuding the feeling of “we’re different to you and that makes us better”.&lt;/p&gt;  &lt;p&gt;Lets look at &lt;a href="http://en.wiktionary.org/wiki/alternative"&gt;the dictionary definition of alternative&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;ol&gt;     &lt;li&gt;A situation which allows a mutually exclusive choice between two or more possibilities. &lt;/li&gt;      &lt;li&gt;A choice between two or more mutually exclusive possibilities. &lt;/li&gt;      &lt;li&gt;One of several mutually exclusive things which can be chosen. &lt;/li&gt;   &lt;/ol&gt; &lt;/blockquote&gt;  &lt;p&gt;It’s all about choosing between different things and can give the impression of “it’s our way or the wrong way”.&lt;/p&gt;  &lt;p&gt;Progressive .NET (could be similarly shortened to PROG.NET) could soften the message of the ALT.NET movement whilst having the same meaning.&lt;/p&gt;  &lt;p&gt;For contrast, lets look at &lt;a href="http://en.wiktionary.org/wiki/progressive"&gt;the dictionary definition of progressive&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;ol&gt;     &lt;li&gt;Favouring or promoting progress; advanced. &lt;/li&gt;      &lt;li&gt;Gradually advancing in extent; increasing. &lt;/li&gt;      &lt;li&gt;Promoting or favouring progress towards improved conditions or new policies, ideas or methods: &lt;dl&gt;&lt;dd&gt;&lt;i&gt;a progressive politician.&lt;/i&gt;&lt;/dd&gt;&lt;dd&gt;&lt;i&gt;progressive business leadership.&lt;/i&gt;&lt;/dd&gt;&lt;/dl&gt;&lt;/li&gt;   &lt;/ol&gt; &lt;/blockquote&gt;  &lt;p&gt;Isn’t progression of the craft of software engineering what ALT.NET is all about?&lt;/p&gt;  &lt;p&gt;To be a part of ALT.NET I get the impression that you have to have mastered IoC, xDD, etc. before you can become a member. PROG.NET gives an altogether softer face, whilst still having the same ideals:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Want to improve your software? So do we, come join in.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Isn’t a message like that going to help ALT.NET &lt;a href="http://en.wikipedia.org/wiki/Technology_adoption_lifecycle"&gt;cross the chasm&lt;/a&gt;? Then again, some will say &lt;a href="http://smallbusiness.yahoo.com/r-article-a-113631-m-6-sc-45-whats_in_a_name_everything-i"&gt;what's in a name&lt;/a&gt;?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-6926690411661343781?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Vzf_VoapebM:IpLX03b_fZc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Vzf_VoapebM:IpLX03b_fZc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Vzf_VoapebM:IpLX03b_fZc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Vzf_VoapebM:IpLX03b_fZc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Vzf_VoapebM:IpLX03b_fZc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Vzf_VoapebM:IpLX03b_fZc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Vzf_VoapebM:IpLX03b_fZc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/Vzf_VoapebM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/6926690411661343781/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=6926690411661343781" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/6926690411661343781?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/6926690411661343781?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/Vzf_VoapebM/new-name-for-altnet.html" title="A new name for ALT.NET" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/05/new-name-for-altnet.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMGQHY5fyp7ImA9WxJSFkw.&quot;"><id>tag:blogger.com,1999:blog-484603982297434662.post-3492644928635849620</id><published>2009-05-06T15:00:00.001+01:00</published><updated>2009-05-06T15:00:21.827+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-06T15:00:21.827+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><title>Difference between AreEqual and AreSame</title><content type="html">&lt;p&gt;This is a question I’ve been asked at work before and the answer is quite important as it can lead to tests mysteriously failing.&lt;/p&gt;  &lt;p&gt;The difference between the two assertions are quite simple. Assert.AreSame checks that they are the exact same object, memory reference and all (in the case of .NET using &lt;a href="http://msdn.microsoft.com/en-us/library/system.object.referenceequals.aspx" target="_blank"&gt;ReferenceEquals&lt;/a&gt;). Assert.AreEqual checks that objectOne.Equals(objectTwo) will return true.&lt;/p&gt;  &lt;p&gt;Here’s a simple example of how they will work with a sensible implementation of Equals.&lt;/p&gt; &lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red204\green120\blue50;\red39\green39\blue39;\red255\green255\blue255;\red255\green198\blue109;\red104\green151\blue187;\red128\green128\blue128;}??\fs20 \cf1\cb2\highlight2 {\b public}\cf3 {\b  }\cf1 {\b class}\cf3 {\b  }\cf4 {\b Example}\par ??\cf3 {\b \{}\par ??{\b     }\cf1 {\b private}\cf3 {\b  }\cf1 {\b int}\cf3 {\b  variable;}\par ??\par ??{\b     }\cf1 {\b public}\cf3 {\b  Example(}\cf1 {\b int}\cf3 {\b  variable)}\par ??{\b     \{}\par ??{\b         }\cf1 {\b this}\cf3 .variable = variable;\par ??{\b     \}}\par ??\par ??{\b     }\cf1 {\b public}\cf3 {\b  }\cf1 {\b override}\cf3 {\b  }\cf1 {\b bool}\cf3 {\b  Equals(}\cf1 {\b object}\cf3 {\b  obj)}\par ??{\b     \{}\par ??{\b         }\cf1 {\b if}\cf3 {\b  (obj }\cf1 {\b is}\cf3 {\b  }\cf4 {\b Example}\cf3 {\b )}\par ??{\b             }\cf1 {\b return}\cf3 {\b  Equals(obj }\cf1 {\b as}\cf3 {\b  }\cf4 {\b Example}\cf3 {\b );}\par ??\par ??{\b         }\cf1 {\b return}\cf3 {\b  }\cf1 {\b base}\cf3 .Equals(obj);\par ??{\b     \}}\par ??\par ??{\b     }\cf1 {\b private}\cf3 {\b  }\cf1 {\b bool}\cf3 {\b  Equals(}\cf4 {\b Example}\cf3 {\b  obj)}\par ??{\b     \{}\par ??{\b         }\cf1 {\b return}\cf3 {\b  variable == obj.variable;}\par ??{\b     \}}\par ??{\b \}}\par ??\par ??{\b [}\cf4 {\b TestFixture}\cf3 {\b ]}\par ??\cf1 {\b public}\cf3 {\b  }\cf1 {\b class}\cf3 {\b  }\cf4 {\b Test}\par ??\cf3 {\b \{}\par ??{\b     [}\cf4 {\b Test}\cf3 {\b ]}\par ??{\b     }\cf1 {\b public}\cf3 {\b  }\cf1 {\b void}\cf3 {\b  ExampleTest()}\par ??{\b     \{}\par ??{\b         }\cf1 {\b var}\cf3 {\b  one = }\cf1 {\b new}\cf3 {\b  }\cf4 {\b Example}\cf3 {\b (}\cf5 {\b 1}\cf3 {\b );}\par ??{\b         }\cf1 {\b var}\cf3 {\b  two = }\cf1 {\b new}\cf3 {\b  }\cf4 {\b Example}\cf3 {\b (}\cf5 {\b 1}\cf3 {\b );}\par ??{\b         }\cf1 {\b var}\cf3 {\b  three = }\cf1 {\b new}\cf3 {\b  }\cf4 {\b Example}\cf3 {\b (}\cf5 {\b 2}\cf3 {\b );}\par ??{\b         }\cf1 {\b var}\cf3 {\b  four = one;}\par ??\par ??{\b         }\cf4 {\b Assert}\cf3 .AreEqual(one, two);   \cf6 {\b // true}\par ??\cf3 {\b         }\cf4 {\b Assert}\cf3 .AreSame(one, two);    \cf6 {\b // false}\par ??\cf3 {\b         }\cf4 {\b Assert}\cf3 .AreEqual(two, three); \cf6 {\b // false}\par ??\cf3 {\b         }\cf4 {\b Assert}\cf3 .AreSame(two, three);  \cf6 {\b // false}\par ??\cf3 {\b         }\cf4 {\b Assert}\cf3 .AreEqual(one, four);  \cf6 {\b // true}\par ??\cf3 {\b         }\cf4 {\b Assert}\cf3 .AreSame(one, four);   \cf6 {\b // true}\par ??\cf3 {\b     \}}\par ??{\b \}}}&lt;br /&gt;--&gt;  &lt;div style="padding-bottom: 0.6em; line-height: 1.2em; font-family: consolas; background: #272727; color: white; font-size: 10pt; font-weight: bold; padding-top: 0.6em"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;Example&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="color: #cc7832"&gt;int&lt;/span&gt; variable;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; Example(&lt;span style="color: #cc7832"&gt;int&lt;/span&gt; variable)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;this&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.variable = variable;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;override&lt;/span&gt; &lt;span style="color: #cc7832"&gt;bool&lt;/span&gt; Equals(&lt;span style="color: #cc7832"&gt;object&lt;/span&gt; obj)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;if&lt;/span&gt; (obj &lt;span style="color: #cc7832"&gt;is&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;Example&lt;/span&gt;)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;return&lt;/span&gt; Equals(obj &lt;span style="color: #cc7832"&gt;as&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;Example&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;return&lt;/span&gt; &lt;span style="color: #cc7832"&gt;base&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.Equals(obj);&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 18&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;private&lt;/span&gt; &lt;span style="color: #cc7832"&gt;bool&lt;/span&gt; Equals(&lt;span style="color: #ffc66d"&gt;Example&lt;/span&gt; obj)&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 19&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 20&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;return&lt;/span&gt; variable == obj.variable;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 21&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 22&lt;/span&gt; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 23&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 24&lt;/span&gt; [&lt;span style="color: #ffc66d"&gt;TestFixture&lt;/span&gt;]&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 25&lt;/span&gt;&amp;#160;&lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;Test&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 26&lt;/span&gt; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 27&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color: #ffc66d"&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 28&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832"&gt;void&lt;/span&gt; ExampleTest()&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 29&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 30&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; one = &lt;span style="color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;Example&lt;/span&gt;(&lt;span style="color: #6897bb"&gt;1&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 31&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; two = &lt;span style="color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;Example&lt;/span&gt;(&lt;span style="color: #6897bb"&gt;1&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 32&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; three = &lt;span style="color: #cc7832"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d"&gt;Example&lt;/span&gt;(&lt;span style="color: #6897bb"&gt;2&lt;/span&gt;);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 33&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832"&gt;var&lt;/span&gt; four = one;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 34&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 35&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Assert&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.AreEqual(one, two);&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: gray"&gt;// true&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 36&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Assert&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.AreSame(one, two);&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: gray"&gt;// false&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 37&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Assert&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.AreEqual(two, three); &lt;/span&gt;&lt;span style="color: gray"&gt;// false&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 38&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Assert&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.AreSame(two, three);&amp;#160; &lt;/span&gt;&lt;span style="color: gray"&gt;// false&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 39&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Assert&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.AreEqual(one, four);&amp;#160; &lt;/span&gt;&lt;span style="color: gray"&gt;// true&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 40&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #ffc66d"&gt;Assert&lt;/span&gt;&lt;span style="font-weight: normal"&gt;.AreSame(one, four);&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: gray"&gt;// true&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 41&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af; font-weight: normal"&gt;&amp;#160;&amp;#160; 42&lt;/span&gt; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;So long as you have a sensible Equals method that compares the values of the two objects you can follow these rules:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;If two objects are the same, they will be equal &lt;/li&gt;    &lt;li&gt;If two objects are equal, they may not be the same &lt;/li&gt;    &lt;li&gt;If two objects are not equal, they will not be the same &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So now you’ll know the answer next time someone asks what the difference between Assert.AreEqual and Assert.AreSame is.&lt;/p&gt;  &lt;p style="margin-bottom: 0px"&gt;&lt;em&gt;Related posts:&lt;/em&gt;&lt;/p&gt;  &lt;ul style="margin-top: 0px"&gt;   &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2008/01/more-fluent-assertions-using-extension.html"&gt;More fluent assertions using extension methods&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/02/test-aided-development.html"&gt;Test aided development&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.robustsoftware.co.uk/2009/05/beauty-of-rspec.html"&gt;Beauty of RSpec&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/484603982297434662-3492644928635849620?l=blog.robustsoftware.co.uk' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Kg3Z0zV15q4:pK2SnLazEbQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Kg3Z0zV15q4:pK2SnLazEbQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Kg3Z0zV15q4:pK2SnLazEbQ:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Kg3Z0zV15q4:pK2SnLazEbQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Kg3Z0zV15q4:pK2SnLazEbQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Kg3Z0zV15q4:pK2SnLazEbQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Kg3Z0zV15q4:pK2SnLazEbQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/Kg3Z0zV15q4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.robustsoftware.co.uk/feeds/3492644928635849620/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=484603982297434662&amp;postID=3492644928635849620" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3492644928635849620?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/484603982297434662/posts/default/3492644928635849620?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobustSoftware/~3/Kg3Z0zV15q4/difference-between-areequal-and-aresame.html" title="Difference between AreEqual and AreSame" /><author><name>Garry Shutler</name><uri>http://www.blogger.com/profile/02687238400432537215</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11971719723059046789" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.robustsoftware.co.uk/2009/05/difference-between-areequal-and-aresame.html</feedburner:origLink></entry></feed>
