<?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;CUMGQ387eCp7ImA9WxBbGUw.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230</id><updated>2010-03-18T07:57:02.100-04:00</updated><title>The Untitled Blog</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.stevehorn.cc/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>114</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/foremanbob" /><feedburner:info uri="foremanbob" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;AkUAQ3oyfip7ImA9WxBbFks.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-4328405656216754221</id><published>2010-03-13T21:53:00.002-05:00</published><updated>2010-03-15T11:50:42.496-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-15T11:50:42.496-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><category scheme="http://www.blogger.com/atom/ns#" term="Agile" /><category scheme="http://www.blogger.com/atom/ns#" term="Moq" /><title>Comparing and Contrasting Moq and Rhino Mocks</title><content type="html">&lt;p&gt;My friend &lt;a href="http://jonkruger.com/blog/2010/03/12/how-to-use-rhino-mocks-documented-through-tests/"&gt;Jon&lt;/a&gt; is starting a &lt;a href="http://tddbootcamp.com/"&gt;training course&lt;/a&gt; in an effort to quickly bring developers up to speed on test driven development.  As part of this effort, he has developed a unit test suite aimed at helping folks understand Rhino Mocks, a popular testing tool.  After looking through the tests and seeing a lot of the Rhino API that I wasn’t familiar with, I wondered if there were similar undiscovered nooks in my favorite mocking framework: &lt;a href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt;.  &lt;/p&gt;  &lt;p&gt;After getting permission, I took his tests that use Rhino Mocks and implemented them with Moq.  It was a great exercise for not only learning the two APIs, but also for getting a side by side comparison of the frameworks.  The differences in most cases are subtle, and ultimately I found the choice between each to be a matter of taste.&lt;/p&gt;  &lt;p&gt;You can find Jon’s tests &lt;a href="http://jonkruger.com/blog/2010/03/12/how-to-use-rhino-mocks-documented-through-tests/"&gt;here&lt;/a&gt;, and mine &lt;a href="http://moqexamples.codeplex.com/"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;h2&gt;Points of Interest&lt;/h2&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;  &lt;br /&gt;Mocks &amp;amp; Stubs?&lt;/h3&gt;  &lt;p&gt;I’m in agreement with Jon that the differences between mocks and stubs are mostly semantic, and are best reserved for academic discussions.  I called all the variables in my tests “mock” because the class for creating mocks &lt;strong&gt;and&lt;/strong&gt; stubs with Moq is “Mock”.  &lt;/p&gt;  &lt;h3&gt;API Surface&lt;/h3&gt;  &lt;p&gt;The reason I am such a fan of Moq is that the API “surface” is minimalistic.  The methods I want to use most often are within clear sight and meaningful.  There’s not a lot of extra jargon and noise that I have to think about.  The methods that I use 20% of the time are tucked away in a manner that is still discoverable, but yet hidden enough to give me a signal that they’re not the first path I should choose.&lt;/p&gt;  &lt;p&gt;When I want to create a mock with Moq I have one choice:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_KdHZl3mpBzc/S5xPg4YREFI/AAAAAAAAA3Y/H_peuQVU2B8/s1600-h/Capture%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Capture" border="0" alt="Capture" src="http://lh3.ggpht.com/_KdHZl3mpBzc/S5xPha6hLLI/AAAAAAAAA3c/YwuItw1HsQ8/Capture_thumb.png?imgmax=800" width="262" height="17" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;With Rhino I have several choices:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_KdHZl3mpBzc/S5xPif9K9SI/AAAAAAAAA3g/x69zhy_RdGo/s1600-h/rhinooptions%5B2%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="rhinooptions" border="0" alt="rhinooptions" src="http://lh5.ggpht.com/_KdHZl3mpBzc/S5xPiyExtWI/AAAAAAAAA3k/042VWlnzklM/rhinooptions_thumb.jpg?imgmax=800" width="346" height="147" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;The more decisions I’m forced to make, the more disruptive the API becomes.&lt;/p&gt;  &lt;h3&gt;Jargon Watch &amp;amp; API Clarity&lt;/h3&gt;  &lt;p&gt;A few examples of pros/cons of the APIs&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Creating a mock of a concrete class with virtual methods&lt;/strong&gt;    &lt;br /&gt;…in Rhino Mocks:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_KdHZl3mpBzc/S5xPj5BLCDI/AAAAAAAAA3o/NkOWerImxkk/s1600-h/Capture%5B11%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Capture" border="0" alt="Capture" src="http://lh4.ggpht.com/_KdHZl3mpBzc/S5xPkJNzTBI/AAAAAAAAA3s/D1Hk-Ovs_ik/Capture_thumb%5B3%5D.png?imgmax=800" width="427" height="50" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;In Moq:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_KdHZl3mpBzc/S5xPkY51K-I/AAAAAAAAA3w/5YJdRg1AokQ/s1600-h/Capture%5B8%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Capture" border="0" alt="Capture" src="http://lh6.ggpht.com/_KdHZl3mpBzc/S5xPlbDEwLI/AAAAAAAAA30/z4FGCoieAAk/Capture_thumb%5B2%5D.png?imgmax=800" width="258" height="21" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The simplicity of Moq’s API shines.  (Replay?*)&lt;/p&gt;  &lt;p&gt;*Replay is a concept that was prevalent in prior versions of Rhino Mocks and it continues to necessitate appearances.  The record/replay syntax is still available for backward compatibility, which adds to the verbosity of the API.  &lt;a href="http://www.ayende.com/wiki/Rhino+Mocks+Record-playback+Syntax.ashx"&gt;Read more about record/replay.&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Finding the arguments passed to a stubbed method&lt;/strong&gt;    &lt;br /&gt;…in Rhino Mocks:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_KdHZl3mpBzc/S5xPmrL8kQI/AAAAAAAAA34/vfxlLLXf2Rg/s1600-h/Capture%5B14%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Capture" border="0" alt="Capture" src="http://lh6.ggpht.com/_KdHZl3mpBzc/S5xPoagUwhI/AAAAAAAAA38/OodGqCUuU_g/Capture_thumb%5B4%5D.png?imgmax=800" width="718" height="134" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In Moq:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_KdHZl3mpBzc/S5xPqa1hzqI/AAAAAAAAA4A/6uuYSFRQYPo/s1600-h/Capture%5B20%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Capture" border="0" alt="Capture" src="http://lh4.ggpht.com/_KdHZl3mpBzc/S5xPrhOxWoI/AAAAAAAAA4E/dfKZqxdjYl0/Capture_thumb%5B6%5D.png?imgmax=800" width="453" height="146" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I prefer the Rhino syntax in this case.  The concept of a “callback” is clear enough, but it is not clear that I should be using it to perform checks on passed arguments.  &lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h3&gt;Feature Parity&lt;/h3&gt;  &lt;p&gt;There are some features that are exclusive to the current versions of the libraries:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Ref Arguments&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Rhino Mocks provides full support for methods with Ref arguments.  Moq does not seem to. (I have an ignored failing test in my code.  If you know how to make it pass please let me know!)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Mocking Protected Methods&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Moq provides built-in support for mocking protected methods.  You can still test protected methods with Rhino mocks, but you’ll have to write some reflection code to do so.&lt;/p&gt;  &lt;h2&gt;Conclusion&lt;/h2&gt;  &lt;p&gt;I favor the style and feel of the Moq API for some of the reasons described above, but as they say: “To each his own!”  Hopefully you’ll find the side by side comparison helpful in determining your preferred mocking framework.  &lt;/p&gt;  &lt;p&gt;Have I missed anything?  Please let me know if I’ve misrepresented or missed critical information that would help to clarify this comparison.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5996062652829415230-4328405656216754221?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/XZ5KyLlT7lc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/4328405656216754221/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=4328405656216754221" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/4328405656216754221?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/4328405656216754221?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/XZ5KyLlT7lc/more-exploring-and-comparing-moq-to.html" title="Comparing and Contrasting Moq and Rhino Mocks" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2010/03/more-exploring-and-comparing-moq-to.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUBSXc_fip7ImA9WxBUGU8.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-3450809846902643136</id><published>2010-03-06T17:35:00.002-05:00</published><updated>2010-03-06T19:37:38.946-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-06T19:37:38.946-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><category scheme="http://www.blogger.com/atom/ns#" term="Agile" /><title>Another Industry Coping with Wicked Problems</title><content type="html">&lt;p&gt;Software development is full of wicked problems:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;“[A wicked problem is] a problem that is difficult or impossible to solve because of incomplete, contradictory, and changing requirements that are often difficult to recognize. Moreover, because of complex interdependencies, the effort to solve one aspect of a wicked problem may reveal or create other problems.”  (&lt;a href="http://en.wikipedia.org/wiki/Wicked_problem"&gt;http://en.wikipedia.org/wiki/Wicked_problem&lt;/a&gt;)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;So I began to ask myself how other industries handle wicked problems.  The root of the problem is uncertainty.  It’s hard (impossible?) to be certain that the designs we’re generating are going to produce an elegant solution.  One example I found was the healthcare industry.  Here’s one coping strategy:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;“If we are uncertain about the relative intrinsic merits of any [different]     &lt;br /&gt;treatments, then we cannot be certain about those merits in any given use      &lt;br /&gt;of one of them – as in treating an individual patient.  So it seems irrational      &lt;br /&gt;and unethical to insist one way or another before completion of a suitable      &lt;br /&gt;trial.  Thus the answer to the question, ‘What is the best treatment for the      &lt;br /&gt;patient?’ is: ‘The trial’.  The trial is the treatment.  Is this experimentation?      &lt;br /&gt;Yes.  But all we mean by that is choice under uncertainty, plus data      &lt;br /&gt;collection.  Does it matter that the choice is ‘random’?  Logically, no.  After      &lt;br /&gt;all, what better mechanism is there for choice under uncertainty?”&lt;/p&gt;    &lt;p&gt;&lt;em&gt;Ashcroft R. Giving medicine a fair trial. British Medical Journal 2000;320:1686. &lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This author’s antidote to uncertainty in medicine?  Learning, trial, and experimentation.  &lt;/p&gt;  &lt;p&gt;We need to test the viability of the new ideas we come up with so we can choose the best one.  &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;If only there were only some way to apply this practice to software development!&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/5996062652829415230-3450809846902643136?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/MzAWW7_6vNg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/3450809846902643136/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=3450809846902643136" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/3450809846902643136?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/3450809846902643136?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/MzAWW7_6vNg/another-industry-coping-with-wicked.html" title="Another Industry Coping with Wicked Problems" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2010/03/another-industry-coping-with-wicked.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkAHQXw6eyp7ImA9WxBXF0w.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-7385269572213338808</id><published>2010-01-28T16:38:00.001-05:00</published><updated>2010-01-28T16:38:50.213-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-28T16:38:50.213-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><title>Wiring Up Subsonic via StructureMap</title><content type="html">&lt;p&gt;This post is a guide to configuring Subsonic with Structuremap to ensure the easiest TDD experience possible.&lt;/p&gt;  &lt;p&gt;The first thing I did was generate the code using the SubSonic &lt;a href="http://subsonicproject.com/docs/Using_AdvancedTemplates"&gt;Linq Templates&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Next, it’s just a matter of telling StructureMap all about how to make an instance of SubSonicRepository&amp;lt;T&amp;gt;.&lt;/p&gt;  &lt;p&gt;Here’s the goo that you need to make it all wire up:&lt;/p&gt;  &lt;div style="font-family: consolas; background: #0f0f0f; color: white; font-size: 10pt"&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; font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832; font-weight: bold"&gt;static&lt;/span&gt; &lt;span style="color: #cc7832; font-weight: bold"&gt;void&lt;/span&gt; ConfigureStructureMap()&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; &lt;span style="color: #ffc66d; font-weight: bold"&gt;ObjectFactory&lt;/span&gt;.Initialize(x =&amp;gt;&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;&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; x.UseDefaultStructureMapConfigFile = &lt;span style="color: #cc7832; font-weight: bold"&gt;false&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; x.Scan(scan =&amp;gt;&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;&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;&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; scan.WithDefaultConventions();&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; scan.TheCallingAssembly();&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; scan.AssemblyContainingType&amp;lt;&lt;span style="color: #6897bb; font-weight: bold"&gt;IRepository&lt;/span&gt;&amp;gt;(); &lt;span style="color: #9933cc; font-weight: bold"&gt;//Scans the Subsonic.Core assembly&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;&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;&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; x.ForRequestedType&amp;lt;&lt;span style="color: #6897bb; font-weight: bold"&gt;IQuerySurface&lt;/span&gt;&amp;gt;().TheDefault.Is.ConstructedBy(c =&amp;gt; &lt;span style="color: #cc7832; font-weight: bold"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d; font-weight: bold"&gt;SomeDB&lt;/span&gt;()); &lt;span style="color: #9933cc; font-weight: bold"&gt;//Gen'd by SubSonic&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; x.ForRequestedType&amp;lt;&lt;span style="color: #6897bb; font-weight: bold"&gt;IDataProvider&lt;/span&gt;&amp;gt;().TheDefault.Is.ConstructedBy(c =&amp;gt; &lt;span style="color: #ffc66d; font-weight: bold"&gt;ProviderFactory&lt;/span&gt;.GetProvider(&lt;span style="color: #86c243; font-weight: bold"&gt;&amp;quot;A_Name_Of_A_Connection_In_Config&amp;quot;&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; x.ForRequestedType(&lt;span style="color: #cc7832; font-weight: bold"&gt;typeof&lt;/span&gt;(&lt;span style="color: #6897bb; font-weight: bold"&gt;IRepository&lt;/span&gt;&amp;lt;&amp;gt;)).TheDefaultIsConcreteType(&lt;span style="color: #cc7832; font-weight: bold"&gt;typeof&lt;/span&gt;(&lt;span style="color: #ffc66d; font-weight: bold"&gt;SubSonicRepository&lt;/span&gt;&amp;lt;&amp;gt;));&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;&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; );&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;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;IRepository&amp;lt;T&amp;gt; and SubSonicRepository&amp;lt;T&amp;gt; are both shipped in the SubSonic.Core DLL, so there’s no real work to do there.&lt;/li&gt;    &lt;li&gt;SomeDB() is a class generated by the Linq Templates mentioned above. &lt;/li&gt;    &lt;li&gt;The string passed to ProviderFactory.GetProvider(“”) is just the name of a connection that you define in your .config file.&amp;#160; You’ll see all this in the examples you downloaded when getting the bits.&lt;/li&gt;    &lt;li&gt;The last line of the config tells StructureMap to map the open generic type to a concrete generic type.&amp;#160; For instance, when you request IRepository&amp;lt;Customer&amp;gt; StructureMap will give you a Repository&amp;lt;Customer&amp;gt;.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Now you can use constructor injection or ObjectFactory.GetInstance&amp;lt;T&amp;gt;() to get a concrete ready-to-go SubSonic repository.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5996062652829415230-7385269572213338808?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/WYYh488e1oU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/7385269572213338808/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=7385269572213338808" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/7385269572213338808?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/7385269572213338808?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/WYYh488e1oU/wiring-up-subsonic-via-structuremap.html" title="Wiring Up Subsonic via StructureMap" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2010/01/wiring-up-subsonic-via-structuremap.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUIERng7eCp7ImA9WxBXE0U.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-3485763398356565072</id><published>2010-01-24T20:38:00.001-05:00</published><updated>2010-01-24T20:38:27.600-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-24T20:38:27.600-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Career" /><title>Values – Practices - Tooling</title><content type="html">&lt;p&gt;Something I heard recently really resonated with me and has already guided me on a few decisions lately.&amp;#160; I’m writing it down here because this idea has really caused a revolution in my mind.&lt;/p&gt;  &lt;p&gt;The quote is this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Values&lt;/strong&gt; lead us to&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;Practices&lt;/strong&gt; which mandate&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;Tooling&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This envelops a lot of thinking and emotion I’ve had in my career as I’ve made choices about how to develop software that I haven’t been able to verbalize.&amp;#160; When I was young in my career as a developer I had that phrase completely inverted.&amp;#160; I made most of my decisions based on the tooling I was given.&amp;#160; For example: when I discovered how to generate 5000 lines of source code to do my database access I immediately leapt and made all my design decisions around that optimization.&amp;#160; Even when my code got complex and unreadable I just kept on thinking about how much time that generated code saved me.&amp;#160; “Certainly the time I’ve saved is paying for the sins I’m committing as I add line number 687 to this method!”&lt;/p&gt;  &lt;h2&gt;What are My Values?&lt;/h2&gt;  &lt;p&gt;After introspecting on this question I came up with 5 core values I have as a software craftsman (in no order):&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Quality (clean code that works) &lt;/li&gt;    &lt;li&gt;Simple designs &lt;/li&gt;    &lt;li&gt;Learning&lt;/li&gt;    &lt;li&gt;Creativity &lt;/li&gt;    &lt;li&gt;Team &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;These values have led me to these practices:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Code designed by testing (TDD) &lt;/li&gt;    &lt;li&gt;Question abstractions before implementation &lt;/li&gt;    &lt;li&gt;Simple team communication mechanisms&lt;/li&gt;    &lt;li&gt;Continuous integration &lt;/li&gt;    &lt;li&gt;Practice (Execute, assess, learn, repeat)&lt;/li&gt;    &lt;li&gt;Improving&lt;/li&gt;    &lt;li&gt;Teaching&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;And ultimately because of these practices I use these tools:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Low-friction source control – supports continuous integration and team integration&lt;/li&gt;    &lt;li&gt;Kanban board – supports simple communication&lt;/li&gt;    &lt;li&gt;Keyboard shortcuts wherever possible – continuous improvement&lt;/li&gt;    &lt;li&gt;Automated scripts - to take care of tasks requiring no creativity &lt;/li&gt;    &lt;li&gt;Frameworks that make testing user code easy&lt;/li&gt;    &lt;li&gt;Continuous integration applications&lt;/li&gt;    &lt;li&gt;…and other frameworks/libraries/IDEs/languages that support my core values &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;These tool choices have to be constantly re-evaluated.&amp;#160; The idea is that I’m constantly pushing to&lt;strong&gt; make the optimal solution feasible &lt;/strong&gt;so that I’m supporting my values as closely as I can.&amp;#160; &lt;/p&gt;  &lt;p&gt;Hat tip to &lt;a href="http://twitter.com/laribee"&gt;Dave Laribee&lt;/a&gt; and &lt;a href="http://twitter.com/stevenharman"&gt;Steven Harman&lt;/a&gt; for sharing this thought at &lt;a href="http://www.codemash.org/"&gt;Codemash 2010&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/5996062652829415230-3485763398356565072?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/4el4vyMO1e4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/3485763398356565072/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=3485763398356565072" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/3485763398356565072?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/3485763398356565072?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/4el4vyMO1e4/values-practices-tooling.html" title="Values – Practices - Tooling" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2010/01/values-practices-tooling.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMEQX49fSp7ImA9WxBSFU0.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-2232353058253574692</id><published>2009-12-22T13:50:00.001-05:00</published><updated>2009-12-22T14:00:00.065-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-22T14:00:00.065-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Career" /><title>Career Goals For 2010 And Inspirations From 2009</title><content type="html">&lt;h1&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;/h1&gt;  &lt;h2&gt;Keep An Eye Out For Simple&lt;/h2&gt;  &lt;p&gt;&lt;strong&gt;Put the user first.     &lt;br /&gt;&lt;/strong&gt;Simple is almost always better for software users.&amp;#160; If your system requires a manual, go back and rethink the user experience elements of your design.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Decisions are made simple by keeping one eye on the value stream.     &lt;br /&gt;&lt;/strong&gt;Daily development and planning decisions are easy when you consider yourself as part of the bigger picture.&amp;#160; You’re probably employed by someone who wants to make or save money, right?&amp;#160; Get an idea for what that value stream looks like, and then optimize it.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Be suspicious of frameworks that promise quicker results.     &lt;br /&gt;&lt;/strong&gt;The lesson I’ve learned here is to understand the abstraction.&amp;#160; When you’re utilizing an abstraction you’re deciding what you can assume.&amp;#160; Make the decision a conscious one. &lt;/p&gt;  &lt;h2&gt;Cease To Acknowledge Irrelevant Concepts&lt;/h2&gt;  &lt;p&gt;&lt;strong&gt;‘Jr’, ‘Sr’, or ‘Architect’ next to job titles.&lt;/strong&gt;&amp;#160; &lt;br /&gt;What do these designations mean?&amp;#160; Rhetorical question.    &lt;br /&gt;I recommend “apprentice, journeyman, master”. These titles add communication and meaning to responsibilities of individuals on a team.&amp;#160; It’s also a reflection of what should be a team’s primary goal: to learn.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Programmer as laborer.&lt;/strong&gt;&amp;#160; &lt;br /&gt;Best explained by &lt;a href="http://blog.objectmentor.com/articles/category/uncle-bobs-blatherings"&gt;this article&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Estimating in hours.     &lt;br /&gt;&lt;/strong&gt;We all know that estimating in hours is dumb… so why continue to justify it’s existence as a professional developer?&amp;#160; What’s the alternative?&amp;#160; Derive your release schedule.&amp;#160; Research more by reading &lt;a href="http://www.amazon.com/Agile-Estimating-Planning-Mike-Cohn/dp/0131479415"&gt;this book&lt;/a&gt;.&lt;/p&gt;  &lt;h2&gt;Always Be Improving&lt;/h2&gt;  &lt;p&gt;&lt;strong&gt;Be part of a team, and build a culture of learning.     &lt;br /&gt;&lt;/strong&gt;My conviction is that only established enduring teams can really approach greatness at building software.&amp;#160; Swapping developers from project to project is a recipe for mediocrity.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Read more     &lt;br /&gt;&lt;/strong&gt;On my list:     &lt;br /&gt;&lt;a href="http://www.amazon.com/Leading-Lean-Software-Development-Results/dp/0321620704/ref=wl_it_dp_o?ie=UTF8&amp;amp;coliid=I1Z7M31BO15LSG&amp;amp;colid=1R0ETLI64OHMS"&gt;Leading Lean Software Development: Results Are not the Point&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://www.amazon.com/Pragmatic-Programmer-Journeyman-Master/dp/020161622X/ref=wl_it_dp_o?ie=UTF8&amp;amp;coliid=I3JYGJVBA4OIHU&amp;amp;colid=1R0ETLI64OHMS"&gt;The Pragmatic Programmer: From Journeyman to Master&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530/ref=wl_it_dp_o?ie=UTF8&amp;amp;coliid=I2D9K182TBFQBV&amp;amp;colid=1R0ETLI64OHMS"&gt;Test Driven Development: By Example&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=wl_it_dp_o?ie=UTF8&amp;amp;coliid=I11QG2FQNNOVS3&amp;amp;colid=1R0ETLI64OHMS"&gt;Clean Code: A Handbook of Agile Software Craftsmanship&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/5996062652829415230-2232353058253574692?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/1xL9AcTJEQ4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/2232353058253574692/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=2232353058253574692" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/2232353058253574692?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/2232353058253574692?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/1xL9AcTJEQ4/career-goals-for-2010.html" title="Career Goals For 2010 And Inspirations From 2009" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2009/12/career-goals-for-2010.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUESXc7eip7ImA9WxNaEkQ.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-7950470643304189680</id><published>2009-11-05T21:49:00.001-05:00</published><updated>2009-11-26T22:40:08.902-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-26T22:40:08.902-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SQL Server" /><category scheme="http://www.blogger.com/atom/ns#" term="SQL" /><title>Fun With Data: SQL Server Unpivot</title><content type="html">&lt;p&gt;My dad ran for a township trustee seat this past election, so I helped him organize some data he got from the Board of Elections.&amp;#160; I massaged and finagled it into a SQL Server table in the format seen below:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_KdHZl3mpBzc/Sw9KDhGY50I/AAAAAAAAA2U/AFUMsXFJzis/s1600-h/Capture%5B1%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Capture" border="0" alt="Capture" src="http://lh5.ggpht.com/_KdHZl3mpBzc/SvOOt_n2TEI/AAAAAAAAA2Y/BMcq7YR0p64/Capture_thumb.png?imgmax=800" width="650" height="251" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This table has all registered voters for the township he was running in.&lt;/p&gt;  &lt;p&gt;I started to wonder about the frequency that people vote.&amp;#160; How many people voted 0/4 years, 1/4 years, 2/4 years, etc.:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_KdHZl3mpBzc/SvOOuKcjlUI/AAAAAAAAA10/z_pzaYMwNR8/s1600-h/results%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="results" border="0" alt="results" src="http://lh5.ggpht.com/_KdHZl3mpBzc/SvOOuYrQaMI/AAAAAAAAA14/BeV6xDSQR4E/results_thumb.png?imgmax=800" width="166" height="146" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Well, lucky for me I’m working with &lt;a href="http://betterlivingthroughcoding.blogspot.com/"&gt;Paul Montgomery&lt;/a&gt; who happens to be a whiz at all things SQL Server and he gave me a hand.&lt;/p&gt;  &lt;p&gt;The first step in solving this challenge is manipulating the data so each voter has one row per year voted.&amp;#160; Paul pointed me to the UNPIVOT keyword.&amp;#160; UNPIVOT rotates columns into rows:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;select * from (      &lt;br /&gt;SELECT * FROM Voters) src       &lt;br /&gt;UNPIVOT (Voted FOR [Year] IN (Voted200905, Voted200811, Voted200803, Voted2007)) unpvt&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This query gives me this result:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_KdHZl3mpBzc/SvOOuzySsUI/AAAAAAAAA2g/XzfomQTD-V4/s1600-h/unpivot%5B1%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="unpivot" border="0" alt="unpivot" src="http://lh4.ggpht.com/_KdHZl3mpBzc/SvOOwU37rAI/AAAAAAAAA2o/jaxfKf1Z8wY/unpivot_thumb%5B1%5D.png?imgmax=800" width="650" height="239" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Now I can group by the voter’s ID and sum the times they voted.&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;SELECT VoterID, Years = SUM(CAST(Voted AS TINYINT)) FROM (      &lt;br /&gt;SELECT * FROM Voters.dbo.Voters) src       &lt;br /&gt;UNPIVOT (Voted FOR [Year] IN (Voted200905, Voted200811, Voted200803, Voted2007)) unpvt       &lt;br /&gt;GROUP BY VoterId&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_KdHZl3mpBzc/SvOOwVlv9JI/AAAAAAAAA2E/h2hinDPYwrg/s1600-h/grouped%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="grouped" border="0" alt="grouped" src="http://lh6.ggpht.com/_KdHZl3mpBzc/SvOOwjt0xvI/AAAAAAAAA2I/l1jj_lZ5xMQ/grouped_thumb.png?imgmax=800" width="129" height="135" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now I just need to group by the “Years” column and I’ve got my result:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;SELECT Years, count(1) as Voters FROM (      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SELECT VoterID, Years = SUM(CAST(Voted AS TINYINT))       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; FROM (SELECT * FROM Voters.dbo.Voters) src       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; UNPIVOT (Voted FOR [Year] IN (Voted200905, Voted200811, Voted200803, Voted2007)) unpvt       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; GROUP BY voterId) voters       &lt;br /&gt;GROUP BY Years       &lt;br /&gt;ORDER BY Years&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_KdHZl3mpBzc/SvOOx4hZ2vI/AAAAAAAAA2M/juL5u5K5Emc/s1600-h/results%5B5%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="results" border="0" alt="results" src="http://lh4.ggpht.com/_KdHZl3mpBzc/SvOOyMzoxcI/AAAAAAAAA2Q/6nm-OQqmR0o/results_thumb%5B1%5D.png?imgmax=800" width="166" height="146" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Only 355 of the 5091 registered voters (which already is a small subset of the population) voted in all 4 of the elections I had data for!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5996062652829415230-7950470643304189680?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/M6pFaipFwiM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/7950470643304189680/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=7950470643304189680" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/7950470643304189680?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/7950470643304189680?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/M6pFaipFwiM/fun-with-data-sql-server-unpivot.html" title="Fun With Data: SQL Server Unpivot" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2009/11/fun-with-data-sql-server-unpivot.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIDRXY8eip7ImA9WxNWGUs.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-2577481995007050177</id><published>2009-10-19T12:09:00.001-04:00</published><updated>2009-10-19T12:09:34.872-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-19T12:09:34.872-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Speaking" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net" /><title>ASP.Net MVC Firestarter</title><content type="html">&lt;p&gt;&lt;a href="http://blog.timwingfield.com/"&gt;Tim Wingfield&lt;/a&gt; and I gave a talk on “Intro to ASP.Net MVC” in Cincinnati as part of the MVC Firestarter.&amp;#160; Slides/code and everything else from each one of the talks has been posted to the &lt;a href="http://cinnug.org/files/folders/mvcfirestarter/default.aspx"&gt;CINNUG website&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;If you had any questions you were burning to ask but didn’t have time, you know &lt;a href="http://www.facebook.com/stevehorn?ref=profile"&gt;how&lt;/a&gt; &lt;a href="http://www.linkedin.com/in/shorn"&gt;to&lt;/a&gt; &lt;a href="mailto:steve@stevehorn.cc"&gt;reach&lt;/a&gt; &lt;a href="http://www.twitter.com/stevehorn"&gt;me&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/5996062652829415230-2577481995007050177?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/T4OIra4N7IY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/2577481995007050177/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=2577481995007050177" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/2577481995007050177?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/2577481995007050177?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/T4OIra4N7IY/aspnet-mvc-firestarter.html" title="ASP.Net MVC Firestarter" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2009/10/aspnet-mvc-firestarter.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08FSXgzcCp7ImA9WxJVGEU.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-4867085207481673158</id><published>2009-07-06T09:30:00.001-04:00</published><updated>2009-07-06T10:16:58.688-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-06T10:16:58.688-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><title>An Opinion on Repository</title><content type="html">&lt;p&gt;First, what is a repository?&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;…Therefore, use a Repository, the purpose of which is to      &lt;br /&gt;encapsulate all the logic needed to obtain object references. The       &lt;br /&gt;domain objects won’t have to deal with the infrastructure to get       &lt;br /&gt;the needed references to other objects of the domain. They will       &lt;br /&gt;just get them from the Repository and the model is regaining its       &lt;br /&gt;clarity and focus.       &lt;br /&gt;      &lt;br /&gt;Excerpt from &lt;a href="http://www.infoq.com/minibooks/domain-driven-design-quickly"&gt;Domain Driven Design Quickly&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;So what the author is saying is that the repository’s (single) responsibility is to encapsulate the logic for obtaining object references. What that means to me is that the class utilizing the repository should be querying it in clear terms, such as:&lt;/p&gt;  &lt;div style="background: #0f0f0f" color="white" size="10pt" face="consolas"&gt;   &lt;p style="margin: 0px"&gt;&lt;font color="#ffffff" size="2" face="Consolas"&gt;_repository.GetPendingOrdersFor(customer);&lt;/font&gt;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This interface keeps the behavior of the method calling the repository focused on it’s job, and eliminates querying logic. Not only that, but the intention of the code is clear and even human(non-developer) readable.&lt;/p&gt;  &lt;p&gt;The alternative is:&lt;/p&gt;  &lt;div style="font-family: consolas; background: #0f0f0f; color: white; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;_respository.Query&amp;lt;&lt;span style="color: #ffc66d; font-weight: bold"&gt;Order&lt;/span&gt;&amp;gt;(o =&amp;gt; o.CustomerID = customer.CustomerID &amp;amp;&amp;amp; o.Status == &lt;span style="color: #ffc66d; font-weight: bold"&gt;OrderStatus&lt;/span&gt;.Pending);&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Here’s how these options would look as an interface.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_KdHZl3mpBzc/Sk63PwlA-tI/AAAAAAAAA1E/UpOyc1pIahs/s1600-h/repository%5B8%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="repository" border="0" alt="repository" src="http://lh5.ggpht.com/_KdHZl3mpBzc/Sk63QFwCKbI/AAAAAAAAA1I/7yECYRirCdI/repository_thumb%5B2%5D.png?imgmax=800" width="412" height="323" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Just one man’s opinion. What do you think? &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5996062652829415230-4867085207481673158?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/5HQEQfppwDE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/4867085207481673158/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=4867085207481673158" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/4867085207481673158?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/4867085207481673158?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/5HQEQfppwDE/opinion-on-repository.html" title="An Opinion on Repository" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2009/07/opinion-on-repository.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcER389fip7ImA9WxJVEU0.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-4200556365448681359</id><published>2009-07-01T09:30:00.000-04:00</published><updated>2009-06-27T08:50:06.166-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-27T08:50:06.166-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net" /><title>ASP.Net MVC: Intro To MVCContrib TestHelpers</title><content type="html">&lt;p&gt;MVCContrib contains an assembly specifically built to provide help when unit testing ASP.Net MVC controller actions.&amp;#160; This is a very condensed guide to what you can accomplish using each helper method.&lt;/p&gt;  &lt;h2&gt;Test View Rendering&lt;/h2&gt;  &lt;p&gt;Test that a view is being rendered from the action:&lt;/p&gt;  &lt;div style="font-family: consolas; background: #0f0f0f; color: white; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;_controller.List().AssertViewRendered();&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;…for a particular view&lt;/p&gt;  &lt;div style="font-family: consolas; background: #0f0f0f; color: white; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;_controller.List().AssertViewRendered().ForView(&lt;span style="color: #86c243; font-weight: bold"&gt;&amp;quot;SomeViewName&amp;quot;&lt;/span&gt;);&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;…with a view model of the correct type&lt;/p&gt;  &lt;div style="font-family: consolas; background: #0f0f0f; color: white; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;_controller.List().AssertViewRendered().ForView(&lt;span style="color: #86c243; font-weight: bold"&gt;&amp;quot;List&amp;quot;&lt;/span&gt;).WithViewData&amp;lt;&lt;span style="color: #ffc66d; font-weight: bold"&gt;SomeType&lt;/span&gt;&amp;gt;();&lt;/p&gt; &lt;/div&gt;  &lt;h2&gt;Test PartialView Rendering&lt;/h2&gt;  &lt;p&gt;Test that a partial view is being rendered from the action:&lt;/p&gt;  &lt;div style="font-family: consolas; background: #0f0f0f; color: white; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: bold"&gt;_controller.ShowAsteroid().AssertPartialViewRendered();&lt;/span&gt;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;…for a particular view&lt;/p&gt;  &lt;div style="font-family: consolas; background: #0f0f0f; color: white; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: bold"&gt;_controller.ShowAsteroid().AssertPartialViewRendered().ForView(&lt;/span&gt;&lt;span style="color: #86c243; font-weight: bold"&gt;&amp;quot;Asteroid&amp;quot;&lt;/span&gt;);&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;…with a view model of the correct type&lt;/p&gt;  &lt;div style="font-family: consolas; background: #0f0f0f; color: white; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: bold"&gt;_controller.ShowAsteroid().AssertPartialViewRendered().ForView(&lt;/span&gt;&lt;span style="color: #86c243; font-weight: bold"&gt;&amp;quot;Asteroid&amp;quot;&lt;/span&gt;).WithViewData&amp;lt;&lt;span style="color: #ffc66d; font-weight: bold"&gt;AsteroidModel&lt;/span&gt;&amp;gt;();&lt;/p&gt; &lt;/div&gt;  &lt;h2&gt;Test Redirects&lt;/h2&gt;  &lt;p&gt;Assert that the action redirects to the correct action:&lt;/p&gt;  &lt;div style="font-family: consolas; background: #0f0f0f; color: white; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;_controller.AddFormStar().AssertActionRedirect().ToAction(&lt;span style="color: #86c243; font-weight: bold"&gt;&amp;quot;List&amp;quot;&lt;/span&gt;);&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;…for an action on a different controller:&lt;/p&gt;  &lt;div style="font-family: consolas; background: #0f0f0f; color: white; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;_controller.AddFormStar().AssertActionRedirect().ToController(&lt;span style="color: #86c243; font-weight: bold"&gt;&amp;quot;SomeController&amp;quot;&lt;/span&gt;).ToAction(&lt;span style="color: #86c243; font-weight: bold"&gt;&amp;quot;List&amp;quot;&lt;/span&gt;);&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h2&gt;Easily Stub HttpContext Variables&lt;/h2&gt;  &lt;p&gt;The TestHelper library contains a class (&lt;font face="Courier New"&gt;TestControllerBuilder&lt;/font&gt;) that builds up a complete context for your controller to operate within.&amp;#160; This gives you the ability to easily mock anything that you would normally access from HttpContext.&amp;#160; Here’s an example of usage:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_KdHZl3mpBzc/SkYVelZajOI/AAAAAAAAA00/8QUtbOemsdI/s1600-h/setup%5B2%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="setup" border="0" alt="setup" src="http://lh4.ggpht.com/_KdHZl3mpBzc/SkYVe7FmrII/AAAAAAAAA04/MdYBZSc1MTQ/setup_thumb.png?imgmax=800" width="381" height="130" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The &lt;font face="Courier New"&gt;_builder&lt;/font&gt; variable is what contains all of the dictionaries for Session, ViewData, etc. that you can use to set up all of your stubs.&amp;#160; Example:    &lt;br /&gt;    &lt;br /&gt;&lt;a href="http://lh5.ggpht.com/_KdHZl3mpBzc/SkYVfH0CNgI/AAAAAAAAA08/lQJKHLa5aNk/s1600-h/test%5B2%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="test" border="0" alt="test" src="http://lh4.ggpht.com/_KdHZl3mpBzc/SkYVfa2YKZI/AAAAAAAAA1A/OpE6pW3XmxE/test_thumb.png?imgmax=800" width="569" height="133" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The code in the &lt;font face="Courier New"&gt;ActionUnderTest&lt;/font&gt; method will now be able to access all of the variables just set up in the test.&amp;#160; Couldn’t be easier!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5996062652829415230-4200556365448681359?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/oGUjO6MqYqU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/4200556365448681359/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=4200556365448681359" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/4200556365448681359?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/4200556365448681359?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/oGUjO6MqYqU/aspnet-mvc-intro-to-mvccontrib.html" title="ASP.Net MVC: Intro To MVCContrib TestHelpers" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2009/06/aspnet-mvc-intro-to-mvccontrib.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0MDQno6fCp7ImA9WxJWGEg.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-5171682930102615706</id><published>2009-06-24T08:00:00.001-04:00</published><updated>2009-06-24T09:51:13.414-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-24T09:51:13.414-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Code Snippet" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net" /><title>Tip For Keeping ASP.Net MVC Views Easy To Read</title><content type="html">&lt;p&gt;ASP.Net MVC views are harder to read when they’re built with a lot of escapes between script and HTML, such as:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_KdHZl3mpBzc/Sj7eyVmGErI/AAAAAAAAA0c/SJAQKzhmr_I/s1600-h/escapes%5B14%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="escapes" border="0" alt="escapes" src="http://lh3.ggpht.com/_KdHZl3mpBzc/Sj7eyvU-cHI/AAAAAAAAA0g/1LXQmj6loRs/escapes_thumb%5B4%5D.png?imgmax=800" width="618" height="274" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;There’s really just no good way to make that easy to read using this approach.  &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Using the MVC Futures Repeater Control&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt; Server controls and MVC just don’t sound like they’d go together, but if used for good I believe they can really serve a useful purpose.  The following code snippet achieves the exact same result as above, but reads much cleaner:  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_KdHZl3mpBzc/Sj7ey3d4QRI/AAAAAAAAA0k/Rb00RePjx2E/s1600-h/repeater%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="repeater" border="0" alt="repeater" src="http://lh3.ggpht.com/_KdHZl3mpBzc/Sj7ezD7scSI/AAAAAAAAA0o/cG_42pGB1BM/repeater_thumb.png?imgmax=800" width="437" height="222" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The MVC Futures repeater control gives me a way to display repeating data with a template.  The control is “bound” to the Model.Items collection because I set the name of the repeater to “Items”.&lt;/p&gt;  &lt;p&gt;To get a reference to this control you need to include a reference to the MVC Futures assembly in the web.config:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_KdHZl3mpBzc/Sj7ezYYTF1I/AAAAAAAAA0s/gYuOaTZBxHg/s1600-h/reference%5B8%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="reference" border="0" alt="reference" src="http://lh5.ggpht.com/_KdHZl3mpBzc/Sj7ezud8XnI/AAAAAAAAA0w/OUeU6yjYHMI/reference_thumb%5B2%5D.png?imgmax=800" width="670" height="101" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The complete solution with this code can be downloaded here:&lt;/p&gt; &lt;iframe style="border-bottom: #dde5e9 1px solid; border-left: #dde5e9 1px solid; padding-bottom: 0px; background-color: #ffffff; margin: 3px; padding-left: 0px; width: 240px; padding-right: 0px; height: 26px; border-top: #dde5e9 1px solid; border-right: #dde5e9 1px solid; padding-top: 0px" marginheight="0" src="http://cid-97458ca58614116f.skydrive.live.com/embedrow.aspx/Public/MVC%20Repeater/Repeater.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5996062652829415230-5171682930102615706?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/IdsykXz99yI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/5171682930102615706/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=5171682930102615706" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/5171682930102615706?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/5171682930102615706?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/IdsykXz99yI/tip-for-keeping-aspnet-views-easy-to.html" title="Tip For Keeping ASP.Net MVC Views Easy To Read" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2009/06/tip-for-keeping-aspnet-views-easy-to.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU8NRns4cCp7ImA9WxJWFko.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-6936660450482665077</id><published>2009-06-22T08:00:00.000-04:00</published><updated>2009-06-22T08:31:37.538-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-22T08:31:37.538-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ReSharper" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><title>Run Your Tests With A Keystroke</title><content type="html">&lt;p&gt;Today I was looking for a way to run my unit tests with a keyboard shortcut. I got really tired of grabbing the mouse just to click a button (wow I’m lazy):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_KdHZl3mpBzc/SjhZFMd7NQI/AAAAAAAAA0M/KrahF3SgO_8/s1600-h/testmenu%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="testmenu" border="0" alt="testmenu" src="http://lh6.ggpht.com/_KdHZl3mpBzc/SjhZFcAQWDI/AAAAAAAAA0Q/OR0jeGv7k0s/testmenu_thumb.png?imgmax=800" width="225" height="178" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I knew there had to be a way to kick off a single test using ReSharper – and after a little digging I found the solution. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_KdHZl3mpBzc/SjhZFhtYg4I/AAAAAAAAA0U/LYoe8Cws-QA/s1600-h/keyboardsettings%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="keyboardsettings" border="0" alt="keyboardsettings" src="http://lh3.ggpht.com/_KdHZl3mpBzc/SjhZGFJ209I/AAAAAAAAA0Y/4ZYd5fDFzao/keyboardsettings_thumb.png?imgmax=800" width="757" height="440" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The magic lies in these 4 keyboard mappings. Assign them to something that makes sense to you, and enjoy the benefit of removing just a little more friction from your TDD experience.&lt;/p&gt; &lt;span style="line-height: normal; widows: 2; text-transform: none; font-variant: normal; font-style: normal; text-indent: 0px; border-collapse: separate; font-family: &amp;#39;Times New Roman&amp;#39;; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); font-weight: normal; word-spacing: 0px; font-size-adjust: none; font-stretch: normal" class="Apple-style-span"&gt;&lt;span style="text-align: left; line-height: 16px; font-family: verdana; color: rgb(51,51,51)" class="Apple-style-span"&gt;Previous ReSharper keyboard shortcut tips:&lt;span class="Apple-converted-space"&gt; &lt;/span&gt;      &lt;br /&gt;      &lt;br /&gt;&lt;a style="color: rgb(51,102,153)" href="http://blog.stevehorn.cc/2009/06/resharper-help-when-yellow-screens.html"&gt;Part 9 – Help When Yellow Screens Happen&lt;/a&gt;       &lt;br /&gt;&lt;a style="color: rgb(51,102,153)" href="http://blog.stevehorn.cc/2009/06/resharper-birds-eye-view-of-class-files.html"&gt;Part 8 – Bird’s Eye View of Class Files&lt;/a&gt;       &lt;br /&gt;&lt;a style="color: rgb(51,102,153)" href="http://blog.stevehorn.cc/2009/06/resharper-add-new-files-quickly.html"&gt;Part 7 – Add New Files Quickly&lt;/a&gt;&lt;span class="Apple-converted-space"&gt; &lt;/span&gt;      &lt;br /&gt;&lt;a style="color: rgb(51,102,153)" href="http://blog.stevehorn.cc/2009/02/move-extracted-interfaces-to-their-own.html"&gt;Part 6 - Move Extracted Interfaces to Their Own File using ReSharper&lt;/a&gt;&lt;span class="Apple-converted-space"&gt; &lt;/span&gt;      &lt;br /&gt;&lt;a style="color: rgb(51,102,153)" href="http://blog.stevehorn.cc/2008/06/resharper-find-next-error.html"&gt;Part 5 - Find the Next Error Using ReSharper&lt;/a&gt;&lt;span class="Apple-converted-space"&gt; &lt;/span&gt;      &lt;br /&gt;&lt;a style="color: rgb(51,102,153)" href="http://blog.stevehorn.cc/2008/06/resharper-find-parameter-info.html"&gt;Part 4 - What To Pass?&lt;/a&gt;&lt;span class="Apple-converted-space"&gt; &lt;/span&gt;      &lt;br /&gt;&lt;a style="color: rgb(51,102,153)" href="http://blog.stevehorn.cc/2008/06/resharper-surround-code-regions.html"&gt;Part 3 - Surround Your Code&lt;/a&gt;&lt;span class="Apple-converted-space"&gt; &lt;/span&gt;      &lt;br /&gt;&lt;a style="color: rgb(51,102,153)" href="http://blog.stevehorn.cc/2008/06/resharper-find-implementations.html"&gt;Part 2 - Find Inheritors&lt;/a&gt;&lt;span class="Apple-converted-space"&gt; &lt;/span&gt;      &lt;br /&gt;&lt;a style="color: rgb(51,102,153)" href="http://blog.stevehorn.cc/2008/06/becoming-resharper-keyboard-ninja-part.html"&gt;Part 1 - Quick Documentation View&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5996062652829415230-6936660450482665077?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/KvvJxSCxuk8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/6936660450482665077/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=6936660450482665077" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/6936660450482665077?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/6936660450482665077?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/KvvJxSCxuk8/run-your-tests-with-keystroke.html" title="Run Your Tests With A Keystroke" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2009/06/run-your-tests-with-keystroke.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEIHQXY6fCp7ImA9WxJWE08.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-5230477335518330181</id><published>2009-06-18T08:00:00.001-04:00</published><updated>2009-06-18T08:02:10.814-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-18T08:02:10.814-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ReSharper" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><title>Resharper Help When Yellow Screens Happen</title><content type="html">&lt;p&gt;Ran across a great utility in Resharper to help with code navigation.  It comes in particularly handy when you come across one of these:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_KdHZl3mpBzc/SjOXCdOSPKI/AAAAAAAAAzM/8mE_603gIhE/s1600-h/pwnd%5B4%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="pwnd" border="0" alt="pwnd" src="http://lh6.ggpht.com/_KdHZl3mpBzc/SjOXCg7I9NI/AAAAAAAAAzQ/ApmUTUQxksE/pwnd_thumb%5B2%5D.png?imgmax=800" width="763" height="513" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;To get your app back to working order, Resharper will analyze the stack trace and then show hyperlinks so you can jump into the code that dealt the problem.  Here’s how:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_KdHZl3mpBzc/SjOXhYqNIOI/AAAAAAAAAzk/IU7rso0GdeA/s1600-h/stacktracecopy%5B15%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="stacktracecopy" border="0" alt="stacktracecopy" src="http://lh6.ggpht.com/_KdHZl3mpBzc/SjOXhosow6I/AAAAAAAAAzo/ujjtImzbyc8/stacktracecopy_thumb%5B7%5D.png?imgmax=800" width="461" height="268" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now go back to Visual Studio and launch the Resharper feature (Intelli-J bindings use &lt;strong&gt;CTRL+SHIFT+E&lt;/strong&gt;, Visual Studio bindings use &lt;strong&gt;CTRL+E, T&lt;/strong&gt;).&lt;/p&gt;  &lt;p&gt;When you launch the Stack Trace Explorer, your copied stack trace will already be inserted into the window and all of your user code class names/line numbers will be turned into hyperlinks.  You can now easily click through to your code to see what’s up:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_KdHZl3mpBzc/SjOXDnoYQ5I/AAAAAAAAAzc/R-CuWSFDHYc/s1600-h/click%5B2%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="click" border="0" alt="click" src="http://lh4.ggpht.com/_KdHZl3mpBzc/SjOXD77llII/AAAAAAAAAzg/FgW8AZ4YqvA/click_thumb.png?imgmax=800" width="680" height="272" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Previous ReSharper keyboard shortcut tips: &lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2009/06/resharper-birds-eye-view-of-class-files.html"&gt;Part 8 – Bird’s Eye View of Class Files&lt;/a&gt;  &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2009/06/resharper-add-new-files-quickly.html"&gt;Part 7 – Add New Files Quickly&lt;/a&gt;  &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2009/02/move-extracted-interfaces-to-their-own.html"&gt;Part 6 - Move Extracted Interfaces to Their Own File using ReSharper&lt;/a&gt;  &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/resharper-find-next-error.html"&gt;Part 5 - Find the Next Error Using ReSharper&lt;/a&gt;  &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/resharper-find-parameter-info.html"&gt;Part 4 - What To Pass?&lt;/a&gt;  &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/resharper-surround-code-regions.html"&gt;Part 3 - Surround Your Code&lt;/a&gt;  &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/resharper-find-implementations.html"&gt;Part 2 - Find Inheritors&lt;/a&gt;  &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/becoming-resharper-keyboard-ninja-part.html"&gt;Part 1 - Quick Documentation View&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/5996062652829415230-5230477335518330181?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/h03qqp2haRA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/5230477335518330181/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=5230477335518330181" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/5230477335518330181?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/5230477335518330181?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/h03qqp2haRA/resharper-help-when-yellow-screens.html" title="Resharper Help When Yellow Screens Happen" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2009/06/resharper-help-when-yellow-screens.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4MSXY4eSp7ImA9WxJWEUw.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-2278327298038625974</id><published>2009-06-15T22:21:00.001-04:00</published><updated>2009-06-15T22:23:08.831-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-15T22:23:08.831-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Web" /><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net" /><title>Rendering A Modal Dialog with ASP.Net MVC</title><content type="html">&lt;p&gt;One of the most requested ‘Web 2.0’ features by users is the ability to pop up a “modal” dialog to the user.&amp;#160; There are a couple ways you could implement this functionality, but I’m going to show you a really easy way to do it with ASP.Net MVC.&amp;#160; (Hat tip to &lt;a href="http://jonkruger.com/blog/"&gt;Jon Kruger&lt;/a&gt; for sharing this idea with me.)&lt;/p&gt;  &lt;p&gt;Start with a very simple controller action:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_KdHZl3mpBzc/SjcBsGc-tLI/AAAAAAAAAzs/gB6Loe5Z8B4/s1600-h/controlleraction%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="controlleraction" border="0" alt="controlleraction" src="http://lh4.ggpht.com/_KdHZl3mpBzc/SjcBsklm4pI/AAAAAAAAAzw/MGnN2bxaj7g/controlleraction_thumb.png?imgmax=800" width="433" height="99" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Nothing spectacular going on here.&amp;#160; The “RandomModal” string points to a ASCX file that is in the views directory, and the second parameter is the model that you want the partial view to render:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_KdHZl3mpBzc/SjcBs16692I/AAAAAAAAAz0/SuALNGtZdZA/s1600-h/ascx%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ascx" border="0" alt="ascx" src="http://lh3.ggpht.com/_KdHZl3mpBzc/SjcBtrEF5SI/AAAAAAAAAz4/OtAHGBe-ewY/ascx_thumb.png?imgmax=800" width="592" height="146" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And finally, on the view that is hosting the modal dialog there is a chunk of javascript that makes the call, throws the returned DOM elements into a parent div, and displays the div as a dialog:   &lt;br /&gt;    &lt;br /&gt;&lt;a href="http://lh5.ggpht.com/_KdHZl3mpBzc/SjcBt2-a5wI/AAAAAAAAAz8/5aYM9czvcy4/s1600-h/javascriptcallingaction%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="javascriptcallingaction" border="0" alt="javascriptcallingaction" src="http://lh6.ggpht.com/_KdHZl3mpBzc/SjcBucmlErI/AAAAAAAAA0A/aojB62zWw-s/javascriptcallingaction_thumb.png?imgmax=800" width="789" height="242" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Another place you could implement this pattern is on a grid.&amp;#160; A common request is to click on a row and view more detailed information about the record.&amp;#160; To implement this all you’d need to do is stash a row identifier on the html row, and pass that back to the controller on click.&amp;#160; Something like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_KdHZl3mpBzc/SjcBugU4TkI/AAAAAAAAA0E/sqdKT0crBmg/s1600-h/postforrowdetail%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="postforrowdetail" border="0" alt="postforrowdetail" src="http://lh6.ggpht.com/_KdHZl3mpBzc/SjcBuxIHUlI/AAAAAAAAA0I/ls4plPdy1P8/postforrowdetail_thumb.png?imgmax=800" width="344" height="182" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The complete solution with this code can be downloaded here:&lt;/p&gt; &lt;iframe style="border-bottom: #dde5e9 1px solid; border-left: #dde5e9 1px solid; padding-bottom: 0px; background-color: #ffffff; margin: 3px; padding-left: 0px; width: 240px; padding-right: 0px; height: 26px; border-top: #dde5e9 1px solid; border-right: #dde5e9 1px solid; padding-top: 0px" marginheight="0" src="http://cid-97458ca58614116f.skydrive.live.com/embedrow.aspx/Public/ASP.Net%20MVC%20Modal%20Dialogs/ModalPop.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5996062652829415230-2278327298038625974?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/PaJ8G9aqoBE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/2278327298038625974/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=2278327298038625974" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/2278327298038625974?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/2278327298038625974?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/PaJ8G9aqoBE/rendering-modal-dialog-with-aspnet-mvc.html" title="Rendering A Modal Dialog with ASP.Net MVC" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2009/06/rendering-modal-dialog-with-aspnet-mvc.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQDRHk7fip7ImA9WxJXGEQ.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-3334071125596303288</id><published>2009-06-13T07:42:00.001-04:00</published><updated>2009-06-13T07:42:55.706-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-13T07:42:55.706-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ReSharper" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><title>Resharper: Bird’s Eye View Of Class Files</title><content type="html">&lt;p&gt;When I’m in a unit testing class file, sometimes I have multiple classes in the same file and the file gets pretty large.&amp;#160; It’s times like these when the file structure navigation shortcut comes in handy.&amp;#160; For users with their keybindings set to the Visual Studio scheme, the shortcut is &lt;strong&gt;CTRL+ALT+F&lt;/strong&gt;.&amp;#160; If you’re using the Intelli-J bindings, it’s &lt;strong&gt;CTRL+F11&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_KdHZl3mpBzc/SjOQvea6ZaI/AAAAAAAAAzE/K8eHx4ffUKQ/s1600-h/FileStructure%5B4%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="FileStructure" border="0" alt="FileStructure" src="http://lh6.ggpht.com/_KdHZl3mpBzc/SjOQvnr4bTI/AAAAAAAAAzI/1CCxVR7JT0A/FileStructure_thumb%5B2%5D.png?imgmax=800" width="692" height="723" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Previous ReSharper keyboard shortcut tips:   &lt;br /&gt;    &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2009/06/resharper-add-new-files-quickly.html"&gt;Part 7 – Add New Files Quickly&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2009/02/move-extracted-interfaces-to-their-own.html"&gt;Part 6 - Move Extracted Interfaces to Their Own File using ReSharper&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/resharper-find-next-error.html"&gt;Part 5 - Find the Next Error Using ReSharper&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/resharper-find-parameter-info.html"&gt;Part 4 - What To Pass?&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/resharper-surround-code-regions.html"&gt;Part 3 - Surround Your Code&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/resharper-find-implementations.html"&gt;Part 2 - Find Inheritors&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/becoming-resharper-keyboard-ninja-part.html"&gt;Part 1 - Quick Documentation View&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/5996062652829415230-3334071125596303288?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/_Hw2r380-to" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/3334071125596303288/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=3334071125596303288" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/3334071125596303288?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/3334071125596303288?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/_Hw2r380-to/resharper-birds-eye-view-of-class-files.html" title="Resharper: Bird’s Eye View Of Class Files" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2009/06/resharper-birds-eye-view-of-class-files.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UEQXkzfyp7ImA9WxJXFk4.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-5442740463593342845</id><published>2009-06-10T08:00:00.000-04:00</published><updated>2009-06-10T08:00:00.787-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-10T08:00:00.787-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ReSharper" /><title>Resharper: Add New Files Quickly</title><content type="html">&lt;p&gt;If you’re adding a &lt;strong&gt;class&lt;/strong&gt;, &lt;strong&gt;interface&lt;/strong&gt;, &lt;strong&gt;struct&lt;/strong&gt;, &lt;strong&gt;enum&lt;/strong&gt;, or&lt;strong&gt; new folder&lt;/strong&gt; to your project, then you can use a feature of ReSharper to add that file much quicker than using the menu commands in Visual Studio.&lt;/p&gt;  &lt;p&gt;How do you use this simple shortcut?&amp;#160; Select the node that you want your item to be created in in the solution explorer, and type ALT+Insert.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_KdHZl3mpBzc/SixPsur0g6I/AAAAAAAAAy8/KjyTJmuIYA8/s1600-h/InsertFile%5B3%5D.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="InsertFile" border="0" alt="InsertFile" src="http://lh3.ggpht.com/_KdHZl3mpBzc/SixPtGvyKEI/AAAAAAAAAzA/q8dLq0eQrVI/InsertFile_thumb%5B1%5D.gif?imgmax=800" width="320" height="460" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Previous ReSharper keyboard shortcut tips:   &lt;br /&gt;    &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2009/02/move-extracted-interfaces-to-their-own.html"&gt;Part 6 - Move Extracted Interfaces to Their Own File using ReSharper&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/resharper-find-next-error.html"&gt;Part 5 - Find the Next Error Using ReSharper&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/resharper-find-parameter-info.html"&gt;Part 4 - What To Pass?&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/resharper-surround-code-regions.html"&gt;Part 3 - Surround Your Code&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/resharper-find-implementations.html"&gt;Part 2 - Find Inheritors&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/becoming-resharper-keyboard-ninja-part.html"&gt;Part 1 - Quick Documentation View&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/5996062652829415230-5442740463593342845?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/rqrf6BDT1ww" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/5442740463593342845/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=5442740463593342845" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/5442740463593342845?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/5442740463593342845?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/rqrf6BDT1ww/resharper-add-new-files-quickly.html" title="Resharper: Add New Files Quickly" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2009/06/resharper-add-new-files-quickly.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8FRX85eSp7ImA9WxJXEkQ.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-5144098135648738159</id><published>2009-06-06T09:42:00.001-04:00</published><updated>2009-06-06T10:00:14.121-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-06T10:00:14.121-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><category scheme="http://www.blogger.com/atom/ns#" term="Code Snippet" /><category scheme="http://www.blogger.com/atom/ns#" term="Code Utility" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net" /><category scheme="http://www.blogger.com/atom/ns#" term="Moq" /><title>ASP.Net MVC: Testing Base Controller Methods</title><content type="html">&lt;p&gt;The project that I’m working on now created the need to execute some logic before every controller action in the application executed.&amp;#160; The ASP.Net MVC &lt;font face="Courier New"&gt;Controller&lt;/font&gt; class has a virtual method called &lt;font face="Courier New"&gt;OnActionExecuting&lt;/font&gt; which will allow me to do just what I needed.&amp;#160; The only problem is that testing this bit of logic in the base controller wasn’t straightforward, and took a little research.&amp;#160; This is the solution I came up with:&lt;/p&gt;  &lt;p&gt;The class under test:&lt;/p&gt;  &lt;div style="font-family: consolas; background: #0f0f0f; color: white; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #cc7832; font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832; font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d; font-weight: bold"&gt;BaseController&lt;/span&gt; : &lt;span style="color: #ffc66d; font-weight: bold"&gt;Controller&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; font-weight: bold"&gt;protected&lt;/span&gt; &lt;span style="color: #cc7832; font-weight: bold"&gt;override&lt;/span&gt; &lt;span style="color: #cc7832; font-weight: bold"&gt;void&lt;/span&gt; OnActionExecuting(&lt;span style="color: #ffc66d; font-weight: bold"&gt;ActionExecutingContext&lt;/span&gt; filterContext)&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; ViewData[&lt;span style="color: #86c243; font-weight: bold"&gt;&amp;quot;SomeKey&amp;quot;&lt;/span&gt;] = &lt;span style="color: #86c243; font-weight: bold"&gt;&amp;quot;Coming to you from a base controller!!&amp;quot;&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;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;The test:&lt;/p&gt;  &lt;div style="font-family: consolas; background: #0f0f0f; color: white; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;[&lt;span style="color: #ffc66d; font-weight: bold"&gt;TestFixture&lt;/span&gt;]&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&lt;span style="color: #cc7832; font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832; font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d; font-weight: bold"&gt;BaseControllerTests&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: #ffc66d; font-weight: bold"&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832; font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832; font-weight: bold"&gt;void&lt;/span&gt; Before_executing_an_action_base_controller_should_populate_view_data()&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; font-weight: bold"&gt;var&lt;/span&gt; baseController = &lt;span style="color: #cc7832; font-weight: bold"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d; font-weight: bold"&gt;BaseController&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;span style="color: #cc7832; font-weight: bold"&gt;var&lt;/span&gt; baseControllerAccessor = &lt;span style="color: #cc7832; font-weight: bold"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d; font-weight: bold"&gt;BaseControllerAccessor&lt;/span&gt;(baseController);&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; font-weight: bold"&gt;var&lt;/span&gt; actionExecutingContextMock = &lt;span style="color: #cc7832; font-weight: bold"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d; font-weight: bold"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color: #ffc66d; font-weight: bold"&gt;ActionExecutingContext&lt;/span&gt;&amp;gt;(); &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; baseControllerAccessor.OnActionExecuting(actionExecutingContextMock.Object);&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: #ffc66d; font-weight: bold"&gt;Assert&lt;/span&gt;.That(baseController.ViewData[&lt;span style="color: #86c243; font-weight: bold"&gt;&amp;quot;SomeKey&amp;quot;&lt;/span&gt;], &lt;span style="color: #ffc66d; font-weight: bold"&gt;Is&lt;/span&gt;.EqualTo(&lt;span style="color: #86c243; font-weight: bold"&gt;&amp;quot;Coming to you from a base controller!!&amp;quot;&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;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;The &lt;font face="Courier New"&gt;BaseController OnActionExecuting&lt;/font&gt; method is &lt;font face="Courier New"&gt;protected&lt;/font&gt;, so I had to do some jury-rigging using reflection to actually put the method under test:&lt;/p&gt;  &lt;div style="font-family: consolas; background: #0f0f0f; color: white; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #cc7832; font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832; font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d; font-weight: bold"&gt;BaseControllerAccessor&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; font-weight: bold"&gt;private&lt;/span&gt; &lt;span style="color: #ffc66d; font-weight: bold"&gt;BaseController&lt;/span&gt; _baseController;&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; font-weight: bold"&gt;public&lt;/span&gt; BaseControllerAccessor(&lt;span style="color: #ffc66d; font-weight: bold"&gt;BaseController&lt;/span&gt; baseController)&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; _baseController = baseController;&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; font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832; font-weight: bold"&gt;void&lt;/span&gt; OnActionExecuting(&lt;span style="color: #ffc66d; font-weight: bold"&gt;ActionExecutingContext&lt;/span&gt; context)&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: #ffc66d; font-weight: bold"&gt;MethodInfo&lt;/span&gt; methodInfo = _baseController.GetType().GetMethod(&lt;span style="color: #86c243; font-weight: bold"&gt;&amp;quot;OnActionExecuting&amp;quot;&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;&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: #ffc66d; font-weight: bold"&gt;BindingFlags&lt;/span&gt;.NonPublic | &lt;span style="color: #ffc66d; font-weight: bold"&gt;BindingFlags&lt;/span&gt;.Instance);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; methodInfo.Invoke(_baseController, &lt;span style="color: #cc7832; font-weight: bold"&gt;new&lt;/span&gt; &lt;span style="color: #cc7832; font-weight: bold"&gt;object&lt;/span&gt;[] {context});&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 was a bit of a pain, but the peaceful easy feeling I’m getting from knowing my code is backed up with an automated test makes it all worth it.&lt;/p&gt;  &lt;p&gt;This code can be downloaded &lt;a href="http://cid-97458ca58614116f.skydrive.live.com/self.aspx/Public/BaseControllerTesting/BaseControllerTesting.zip"&gt;here&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/5996062652829415230-5144098135648738159?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/HCEMRyiw4Fo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/5144098135648738159/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=5144098135648738159" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/5144098135648738159?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/5144098135648738159?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/HCEMRyiw4Fo/aspnet-mvc-testing-base-controller.html" title="ASP.Net MVC: Testing Base Controller Methods" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2009/06/aspnet-mvc-testing-base-controller.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0IBQHs5fSp7ImA9WxJQF0U.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-2621583307868863237</id><published>2009-05-31T13:01:00.001-04:00</published><updated>2009-05-31T13:05:51.525-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-31T13:05:51.525-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Agile" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net" /><title>Team Velocity: ASP.Net Webforms and MVC</title><content type="html">&lt;p&gt;Since the release of ASP.Net MVC, one of the major talking points has been: When should I use MVC and/or webforms, and will it save or cost me time.&amp;#160; These are my thoughts.&lt;/p&gt;  &lt;p&gt;Consider the following:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_KdHZl3mpBzc/SiK35d6XoVI/AAAAAAAAAy0/ffihVafj9UA/s1600-h/mvcwebforms%5B9%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="mvcwebforms" border="0" alt="mvcwebforms" src="http://lh5.ggpht.com/_KdHZl3mpBzc/SiK35zBHk6I/AAAAAAAAAy4/5WZwyPP6oP4/mvcwebforms_thumb%5B5%5D.png?imgmax=800" width="400" height="228" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;em&gt;Velocity is the number of feature hours (or feature points) completed in a given iteration (or time period – given that the time period is constant).&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Why does it take longer to gain velocity with MVC?&lt;/strong&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;As ASP.Net web developers we’ve been developing with a mammoth abstraction that’s made a ton of our design decisions for us.&amp;#160; To achieve velocity with webforms, you really needed only a cursory understanding of how the web works.&amp;#160; Contrast that with ASP.Net MVC, which puts developers closer to “the metal” and forces us to make &lt;strong&gt;intentional&lt;/strong&gt; decisions about the design of our apps.&amp;#160; Because of this freedom (and power) we’re also responsible for making sure we don’t make the wrong decisions, so it takes a great deal of critical thought and planning to make it what you want it to be. &lt;/p&gt;  &lt;p&gt;Once your design and opinions have been established, velocity is likely to increase and then stabilize.&amp;#160; Why?&amp;#160; Because if you’re doing it right, then you’re designing with &lt;a href="http://www.lostechies.com/blogs/chad_myers/archive/2008/03/07/pablo-s-topic-of-the-month-march-solid-principles.aspx"&gt;SOLID&lt;/a&gt;* principles in mind (something that’s extremely hard to do with webforms).&amp;#160; Complexity is minimized and entropy is mitigated.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;What’s with the sharp decrease in velocity with webforms?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Because it’s so hard to create &lt;a href="http://www.lostechies.com/blogs/chad_myers/archive/2008/03/07/pablo-s-topic-of-the-month-march-solid-principles.aspx"&gt;SOLID&lt;/a&gt;* apps with webforms, complexity grows and grows until it’s out of hand.&amp;#160; Release cycles go from weeks to months to quarters, and then the app that the company invested millions of dollars in needs to be rewritten because the cost to maintain and/or extend outweighs the cost to start over.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;What do you think?&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;*SOLID principles are not new and whizbangy.&amp;#160; They’re a different name and face on what’s been known about OO since the first OO languages, and what every CS college student should have learned in OO design 101.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5996062652829415230-2621583307868863237?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/pKRjajFIDUY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/2621583307868863237/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=2621583307868863237" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/2621583307868863237?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/2621583307868863237?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/pKRjajFIDUY/aspnet-webforms-and-mvc.html" title="Team Velocity: ASP.Net Webforms and MVC" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2009/05/aspnet-webforms-and-mvc.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QDSH4yfCp7ImA9WxVUFUw.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-2080604381116301963</id><published>2009-03-19T23:22:00.001-04:00</published><updated>2009-03-19T23:22:59.094-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-19T23:22:59.094-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Nhibernate" /><category scheme="http://www.blogger.com/atom/ns#" term="Code Snippet" /><category scheme="http://www.blogger.com/atom/ns#" term="ORM" /><title>Fluent NHibernate Configured Via Dependency Injection</title><content type="html">&lt;p&gt;I remember having to reference this &lt;a href="http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx"&gt;“best practice” post&lt;/a&gt; when setting up a new project utilizing NHibernate.&amp;#160; What a nightmare.&amp;#160; Thankfully, there’s been some really positive activity on the &lt;a href="http://code.google.com/p/fluent-nhibernate/"&gt;Fluent NHibernate project&lt;/a&gt;, and configuration has become much more straightforward.&amp;#160; In this post I am going to share my experience configuring NHibernate using:    &lt;br /&gt;    &lt;br /&gt;Fluent NHibernate    &lt;br /&gt;Ninject    &lt;br /&gt;MySQL (Configuring any common database platform is trivial once you’ve seen it done)    &lt;br /&gt;    &lt;br /&gt;To get my head around the basic configuration, I read the tutorial at the Fluent NHibernate site: &lt;a href="http://fluentnhibernate.org/"&gt;http://fluentnhibernate.org/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;After reading the tutorial, I had a good idea of the external dependencies I’d need to “inject” into my app.&lt;/p&gt;  &lt;h2&gt;Configuring the Repository&lt;/h2&gt;  &lt;p&gt;The primary point of entry for any data transferred to and from my database is via my repository.&amp;#160; NHibernate’s ISession is what I will interface with to make queries, so I’m going to need that object created and injected into my repository.&lt;/p&gt;  &lt;p&gt;Example of a simple repository:&lt;/p&gt;  &lt;div style="font-family: consolas; background: #0f0f0f; color: white; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832; font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832; font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d; font-weight: bold"&gt;Repository&lt;/span&gt; : &lt;span style="color: #6897bb; font-weight: bold"&gt;IRepository&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; font-weight: bold"&gt;private&lt;/span&gt; &lt;span style="color: #6897bb; font-weight: bold"&gt;ISession&lt;/span&gt; _session;&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; font-weight: bold"&gt;public&lt;/span&gt; Repository(&lt;span style="color: #6897bb; font-weight: bold"&gt;ISession&lt;/span&gt; session)&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; _session = session;&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;&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; font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832; font-weight: bold"&gt;void&lt;/span&gt; Save&amp;lt;T&amp;gt;(T entity) &lt;span style="color: #cc7832; font-weight: bold"&gt;where&lt;/span&gt; T : &lt;span style="color: #ffc66d; font-weight: bold"&gt;DomainEntity&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; {&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;&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;&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; font-weight: bold"&gt;public&lt;/span&gt; T Load&amp;lt;T&amp;gt;(&lt;span style="color: #cc7832; font-weight: bold"&gt;int&lt;/span&gt; id) &lt;span style="color: #cc7832; font-weight: bold"&gt;where&lt;/span&gt; T : &lt;span style="color: #ffc66d; font-weight: bold"&gt;DomainEntity&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; }&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; font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #6897bb; font-weight: bold"&gt;IQueryable&lt;/span&gt;&amp;lt;T&amp;gt; Query&amp;lt;T&amp;gt;() &lt;span style="color: #cc7832; font-weight: bold"&gt;where&lt;/span&gt; T : &lt;span style="color: #ffc66d; font-weight: bold"&gt;DomainEntity&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; }&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; font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #6897bb; font-weight: bold"&gt;IQueryable&lt;/span&gt;&amp;lt;T&amp;gt; Query&amp;lt;T&amp;gt;(&lt;span style="color: #ffc66d; font-weight: bold"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #ffc66d; font-weight: bold"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color: #cc7832; font-weight: bold"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; where) &lt;span style="color: #cc7832; font-weight: bold"&gt;where&lt;/span&gt; T : &lt;span style="color: #ffc66d; font-weight: bold"&gt;DomainEntity&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; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;The constructor of my class takes an instance of ISession.&amp;#160; This is where the dependency will be injected into my Repository class.&lt;/p&gt;  &lt;h2&gt;Widdling down the “Best Practice” article&lt;/h2&gt;  &lt;p&gt;The most important part of an NHibernate configuration is your management of the SessionFactory and Session objects.&amp;#160; The SessionFactory object is expensive to create, and should be made a &lt;a href="http://en.wikipedia.org/wiki/Singleton_pattern"&gt;Singleton&lt;/a&gt;.&amp;#160; The ISession object should be retained for the lifecycle of the current request if you’re working on a web application.&amp;#160; For a non-web project the lifecycle of the ISession should be kept around one per thread.&lt;/p&gt;  &lt;p&gt;Many (if not all) of the major dependency injection frameworks offer this type of “lifecycle management” out of the box.&amp;#160; Ninject is no exception; here is how I accomplished it:&lt;/p&gt;  &lt;div style="font-family: consolas; background: #0f0f0f; color: white; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832; font-weight: bold"&gt;internal&lt;/span&gt; &lt;span style="color: #cc7832; font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d; font-weight: bold"&gt;IoCConfiguration&lt;/span&gt; : &lt;span style="color: #ffc66d; font-weight: bold"&gt;StandardModule&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; font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832; font-weight: bold"&gt;override&lt;/span&gt; &lt;span style="color: #cc7832; font-weight: bold"&gt;void&lt;/span&gt; Load()&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; Bind&amp;lt;&lt;span style="color: #6897bb; font-weight: bold"&gt;IRepository&lt;/span&gt;&amp;gt;().To&amp;lt;&lt;span style="color: #ffc66d; font-weight: bold"&gt;Repository&lt;/span&gt;&amp;gt;();&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; Bind&amp;lt;&lt;span style="color: #6897bb; font-weight: bold"&gt;INHibernateSessionFactoryBuilder&lt;/span&gt;&amp;gt;().To&amp;lt;&lt;span style="color: #ffc66d; font-weight: bold"&gt;NHibernateSessionFactoryBuilder&lt;/span&gt;&amp;gt;().Using&amp;lt;&lt;span style="color: #ffc66d; font-weight: bold"&gt;SingletonBehavior&lt;/span&gt;&amp;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;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Bind&amp;lt;&lt;span style="color: #6897bb; font-weight: bold"&gt;ISession&lt;/span&gt;&amp;gt;().ToMethod(ctx =&amp;gt; ctx.Kernel.Get&amp;lt;&lt;span style="color: #6897bb; font-weight: bold"&gt;INHibernateSessionFactoryBuilder&lt;/span&gt;&amp;gt;()&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .GetSessionFactory()&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .OpenSession())&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Using&amp;lt;&lt;span style="color: #ffc66d; font-weight: bold"&gt;OnePerRequestBehavior&lt;/span&gt;&amp;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; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Due to the expressive nature of the API, this code is really self-explanatory.&amp;#160; Just for fun, compare this code with the mess from the NHibernate best practices article I mentioned eariler (&lt;a href="http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx"&gt;http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx&lt;/a&gt;).&amp;#160; &lt;/p&gt;  &lt;p&gt;For completeness, here is the code to configure NHibnerate via Fluent Nhibernate for a MySql database:&lt;/p&gt;  &lt;div style="font-family: consolas; background: #0f0f0f; color: white; font-size: 10pt"&gt;   &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832; font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832; font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d; font-weight: bold"&gt;NHibernateSessionFactoryBuilder&lt;/span&gt; : &lt;span style="color: #6897bb; font-weight: bold"&gt;INHibernateSessionFactoryBuilder&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; font-weight: bold"&gt;private&lt;/span&gt; &lt;span style="color: #6897bb; font-weight: bold"&gt;ISessionFactory&lt;/span&gt; _sessionFactory;&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; font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #6897bb; font-weight: bold"&gt;ISessionFactory&lt;/span&gt; GetSessionFactory()&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; &lt;span style="color: #cc7832; font-weight: bold"&gt;if&lt;/span&gt;(_sessionFactory == &lt;span style="color: #cc7832; font-weight: bold"&gt;null&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;&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _sessionFactory = CreateSessionFactory();&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; }&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cc7832; font-weight: bold"&gt;return&lt;/span&gt; _sessionFactory;&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;&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; font-weight: bold"&gt;private&lt;/span&gt; &lt;span style="color: #6897bb; font-weight: bold"&gt;ISessionFactory&lt;/span&gt; CreateSessionFactory()&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; &lt;span style="color: #cc7832; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #ffc66d; font-weight: bold"&gt;Fluently&lt;/span&gt;.Configure()&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Database(&lt;span style="color: #ffc66d; font-weight: bold"&gt;MySQLConfiguration&lt;/span&gt;.Standard.ConnectionString(c =&amp;gt; c.FromAppSetting(&lt;span style="color: #86c243; font-weight: bold"&gt;&amp;quot;DBConnString&amp;quot;&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Mappings(m =&amp;gt; m.AutoMappings.Add(&lt;span style="color: #ffc66d; font-weight: bold"&gt;AutoPersistenceModel&lt;/span&gt;.MapEntitiesFromAssemblyOf&amp;lt;&lt;strong&gt;&lt;font color="#ffc66d"&gt;DomainClass&lt;/font&gt;&lt;/strong&gt;&amp;gt;()&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;&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; .Where(w =&amp;gt; w.BaseType == &lt;span style="color: #cc7832; font-weight: bold"&gt;typeof&lt;/span&gt;(&lt;span style="color: #ffc66d; font-weight: bold"&gt;DomainEntity&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;&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;&amp;#160;&amp;#160;&amp;#160; .ConventionDiscovery.Add&amp;lt;&lt;span style="color: #ffc66d; font-weight: bold"&gt;PrimaryKeyConvention&lt;/span&gt;&amp;gt;()&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;&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; .WithSetup(convention =&amp;gt; &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;&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;/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;&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;&amp;#160;&amp;#160;&amp;#160; convention.FindIdentity = t =&amp;gt; t.Name == &lt;span style="color: #86c243; font-weight: bold"&gt;&amp;quot;Id&amp;quot;&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;&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; convention.IsBaseType = type =&amp;gt; type == &lt;span style="color: #cc7832; font-weight: bold"&gt;typeof&lt;/span&gt; (&lt;span style="color: #ffc66d; font-weight: bold"&gt;DomainEntity&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;&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;&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;&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;/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;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .BuildSessionFactory();&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;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;This is all best explained by the &lt;a href="http://wiki.fluentnhibernate.org/show/HomePage"&gt;Fluent Nhibernate wiki&lt;/a&gt; (which is excellently written).&lt;/p&gt;  &lt;p&gt;All this is a first swag, and I’d love to hear how it could be improved.&amp;#160; Please leave a comment if you’ve got any questions or if you know of a way it can be better!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5996062652829415230-2080604381116301963?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/-eEWJWuW3y4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/2080604381116301963/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=2080604381116301963" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/2080604381116301963?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/2080604381116301963?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/-eEWJWuW3y4/fluent-nhibernate-configured-via.html" title="Fluent NHibernate Configured Via Dependency Injection" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2009/03/fluent-nhibernate-configured-via.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cFSX4zfSp7ImA9WxVVEks.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-839857829150534816</id><published>2009-03-05T11:01:00.001-05:00</published><updated>2009-03-05T11:03:38.085-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-05T11:03:38.085-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Web" /><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term="Code Snippet" /><category scheme="http://www.blogger.com/atom/ns#" term="Sitefinity" /><title>Content Not Being Indexed in Sitefinity</title><content type="html">&lt;p&gt;This post will be a little esoteric.&amp;#160; I’m working on a Sitefinity project, and one of the features we wanted to implement was the built in site search module.&lt;/p&gt;  &lt;p&gt;After &lt;a href="http://www.sitefinity.com/help/developer-manual/search-overview-and-building-parts.html"&gt;configuring the search module&lt;/a&gt; everything appeared to be working properly, but after looking a little closer we realized that none of our site content was being indexed.&amp;#160; The only thing that was being indexed was each page’s meta tags.&amp;#160; I found out in one of the Sitefinity forums that you can control what gets indexed on the site by using an XML configuration file.&amp;#160; You can find your site’s configuration file in this path: /%AppDirectory%/App_Data/Search/%IndexName%/fieldsInfoProvider.xml&lt;/p&gt;  &lt;p&gt;Here is what the file looks like when you set up a new index:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_KdHZl3mpBzc/Sa_3kH5WAGI/AAAAAAAAAyM/X416tNnxeiQ/s1600-h/fieldsinfoproviderOrig%5B9%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="fieldsinfoproviderOrig" border="0" alt="fieldsinfoproviderOrig" src="http://lh5.ggpht.com/_KdHZl3mpBzc/Sa_3ksELYAI/AAAAAAAAAyQ/tXyAWGuFkNw/fieldsinfoproviderOrig_thumb%5B5%5D.jpg?imgmax=800" width="908" height="196" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Here’s what the attributes mean:   &lt;br /&gt;name= This attribute is for the reader.&amp;#160; You can name it whatever you want.    &lt;br /&gt;weight= Gives weight to the content in the search results.&amp;#160; (Eg: Items weighted higher will return higher in the search results than lesser weighted items)    &lt;br /&gt;indexAttribute= Use this attribute to index all tags with a certain attribute.    &lt;br /&gt;filterTag= Use this to tell Sitefinity that you want to index by tag name.&amp;#160; &lt;br /&gt;filterAttributes= Use this to filter the attributes by value.&lt;/p&gt;  &lt;p&gt;In the site I am building, I want an entire HTML node to be indexed it happens to be:   &lt;br /&gt;    &lt;br /&gt;&amp;lt;div id=”primary”&amp;gt;&amp;lt;/div&amp;gt;&lt;/p&gt;  &lt;p&gt;So to add this content to my index, I added a field node in the fieldsInfoProvider.xml file as such: &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://lh6.ggpht.com/_KdHZl3mpBzc/Sa_3lcA19FI/AAAAAAAAAyU/b7bpVXyE_ag/s1600-h/fieldsinfoprovider%5B15%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="fieldsinfoprovider" border="0" alt="fieldsinfoprovider" src="http://lh4.ggpht.com/_KdHZl3mpBzc/Sa_3mLncdhI/AAAAAAAAAyY/CrnMIT0hVow/fieldsinfoprovider_thumb%5B9%5D.jpg?imgmax=800" width="910" height="223" /&gt;&lt;/a&gt;     &lt;br /&gt;    &lt;br /&gt;If I wanted to add a HTML node by class, I could have changed the filterAttributes= attribute to “class:someCSSClass”.&amp;#160; If my HTML node was a &amp;lt;UL&amp;gt;, I’d change filterTag= “UL”.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5996062652829415230-839857829150534816?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/QPmmz7_YHl4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/839857829150534816/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=839857829150534816" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/839857829150534816?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/839857829150534816?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/QPmmz7_YHl4/content-not-being-indexed-in-sitefinity.html" title="Content Not Being Indexed in Sitefinity" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2009/03/content-not-being-indexed-in-sitefinity.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQHRXg9eip7ImA9WxVWE0g.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-6455626717134451700</id><published>2009-02-22T20:40:00.001-05:00</published><updated>2009-02-22T20:42:14.662-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-22T20:42:14.662-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Web" /><category scheme="http://www.blogger.com/atom/ns#" term="Utility" /><title>Google Chrome “Feeling Lucky Search”</title><content type="html">&lt;p&gt;If you want to do a “Feeling Lucky” search from Google Chrome post haste, I’ve got a great trick for you.&amp;#160; Check this out:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_KdHZl3mpBzc/SaH-g4XFyWI/AAAAAAAAAxk/YYsskyxNTxY/s1600-h/weeb%5B3%5D.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="weeb" border="0" alt="weeb" src="http://lh3.ggpht.com/_KdHZl3mpBzc/SaH-iElRqcI/AAAAAAAAAxo/kWHXRBZ66jQ/weeb_thumb%5B1%5D.gif?imgmax=800" width="568" height="232" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Fewer clicks, happier browsing.&lt;/p&gt;  &lt;p&gt;Here’s how to do it:&lt;/p&gt;  &lt;p&gt;1) Create a custom search engine in Chrome:   &lt;br /&gt;&lt;a href="http://lh5.ggpht.com/_KdHZl3mpBzc/SaH-jOXjcCI/AAAAAAAAAxs/jIklggFikIM/s1600-h/1%5B4%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="1" border="0" alt="1" src="http://lh4.ggpht.com/_KdHZl3mpBzc/SaH-jwFLHHI/AAAAAAAAAxw/F7gEB-A73Ak/1_thumb%5B2%5D.jpg?imgmax=800" width="692" height="603" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;2) Add the search engine with these properties:   &lt;br /&gt;&lt;a href="http://lh3.ggpht.com/_KdHZl3mpBzc/SaH-kaso9OI/AAAAAAAAAx0/sJiCFMMXtFI/s1600-h/2%5B4%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="2" border="0" alt="2" src="http://lh6.ggpht.com/_KdHZl3mpBzc/SaH-kooiEvI/AAAAAAAAAx4/RF7co68BDxE/2_thumb%5B2%5D.jpg?imgmax=800" width="342" height="211" /&gt;&lt;/a&gt;     &lt;br /&gt;URL: http://www.google.com/search?q=%s&amp;amp;btnI=Im+Feeling+Lucky&lt;/p&gt;  &lt;p&gt;3) Enjoy!!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5996062652829415230-6455626717134451700?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/wUsLey1Zodo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/6455626717134451700/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=6455626717134451700" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/6455626717134451700?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/6455626717134451700?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/wUsLey1Zodo/google-chrome-feeling-lucky-search.html" title="Google Chrome “Feeling Lucky Search”" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">8</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2009/02/google-chrome-feeling-lucky-search.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8EQXgyeCp7ImA9WxVQGU4.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-335962424214895570</id><published>2009-02-06T08:30:00.001-05:00</published><updated>2009-02-06T11:30:00.690-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-06T11:30:00.690-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ReSharper" /><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><title>Move Extracted Interfaces to Their Own File using ReSharper</title><content type="html">&lt;p&gt;Update 2/6/09:&lt;/p&gt; &lt;p&gt;Thanks for @orangy for pointing out that there is an even more streamlined approach that I overlooked.&lt;/p&gt; &lt;p&gt;With your cursor on the concrete class use the "Refactor This" keyboard shortcut (CTRL+SHIFT+R), then X.&amp;nbsp; The extract interface dialog pops.&amp;nbsp; &lt;/p&gt; &lt;p&gt;Then use the keyboard shortcut ALT+F to change the radio button to "Place in another file".&amp;nbsp; Then tab through the rest of the controls and make your selections.&lt;/p&gt; &lt;p&gt;Much nicer.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;One thing I do commonly when developing is create a class, and then extract an interface from it.&amp;nbsp; ReSharper makes that easy:&lt;/p&gt; &lt;p&gt;&lt;strike&gt;1) Put your cursor on the concrete class name.&lt;/strike&gt;&lt;/p&gt; &lt;p&gt;&lt;strike&gt;2) Use ReSharper's "Refactor This" keyboard shortcut (CTRL+SHIFT+R).&lt;/strike&gt;&lt;/p&gt; &lt;p&gt;&lt;strike&gt;3) Hit "x" on the keyboard for "extract interface".&lt;/strike&gt;&lt;/p&gt; &lt;p&gt;&lt;strike&gt;A keyboard friendly dialog will open which will allow you to select which members get extracted out into the interface.&amp;nbsp; &lt;/strike&gt;&lt;/p&gt; &lt;p&gt;&lt;strike&gt;So now you have an interface sitting in the same file as your concrete class.&amp;nbsp; That's perfectly acceptable, but I always prefer having each class/interface in it's own file named the same as the class/interface name.&amp;nbsp; To do that, you just need to put your cursor on the interface name and hit "CTRL+Enter, Enter", to select the option for "Move to another file to match type name".&amp;nbsp; &lt;/strike&gt;&lt;/p&gt; &lt;p&gt;Thanks to &lt;a href="http://www.twitter.com/orangy"&gt;www.twitter.com/orangy&lt;/a&gt; for helping me find this shortcut!!&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_KdHZl3mpBzc/SYxlhLsi0JI/AAAAAAAAAxE/_JUcBDABy9k/s1600-h/moveinterface%5B9%5D.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="moveinterface" src="http://lh4.ggpht.com/_KdHZl3mpBzc/SYxlhtUlcjI/AAAAAAAAAxI/hNhhDIo6b6M/moveinterface_thumb%5B5%5D.gif?imgmax=800" width="628" height="432"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;This is part 6 of a series of posts exploring &lt;a href="http://blog.stevehorn.cc/2008/06/becoming-resharper-keyboard-ninja-part.html"&gt;how to become a ReSharper keyboard ninja.&lt;/a&gt;&lt;br&gt;&lt;br&gt;Previously:&lt;br&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/resharper-find-next-error.html"&gt;Part 5 - Find the Next Error Using ReSharper&lt;/a&gt;&lt;br&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/resharper-find-parameter-info.html"&gt;Part 4 - What To Pass?&lt;/a&gt;&lt;br&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/resharper-surround-code-regions.html"&gt;Part 3 - Surround Your Code&lt;/a&gt;&lt;br&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/resharper-find-implementations.html"&gt;Part 2 - Find Inheritors&lt;/a&gt;&lt;br&gt;&lt;a href="http://blog.stevehorn.cc/2008/06/becoming-resharper-keyboard-ninja-part.html"&gt;Part 1 - Quick Documentation View&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/5996062652829415230-335962424214895570?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/7ZZm1eIplc0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/335962424214895570/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=335962424214895570" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/335962424214895570?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/335962424214895570?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/7ZZm1eIplc0/move-extracted-interfaces-to-their-own.html" title="Move Extracted Interfaces to Their Own File using ReSharper" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2009/02/move-extracted-interfaces-to-their-own.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEYARXoycCp7ImA9WxVRF08.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-4361188890568164862</id><published>2009-01-23T09:49:00.001-05:00</published><updated>2009-01-23T09:49:04.498-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-23T09:49:04.498-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term="Agile" /><category scheme="http://www.blogger.com/atom/ns#" term="Career" /><title>Trends For My Industry</title><content type="html">&lt;p&gt;I've been doing the software consulting circuit for a while, although not too long - about 2 years.&amp;nbsp; It's enough time to know that there's a lot of room for improvement, and I'm going to discuss in this blog post what trends I think will emerge as the industry matures.&amp;nbsp; Many of the points I'm going to make are based on observations I've made about software quality, and how organizations will begin to value it more.&lt;/p&gt; &lt;h2&gt;More Emphasis On Partnerships and Trust&lt;/h2&gt; &lt;p&gt;Too many projects end in something less than success.&amp;nbsp; It's time that we change perspectives on software development and become fanatical about achieving our customer's goals.&amp;nbsp; What I think this means is that we completely change our business models.&amp;nbsp; Instead of the old-school fixed bid or time and materials contracts, let's go for more of the incentive based contracts.&amp;nbsp; In other words, I get paid when I've made you money.&amp;nbsp; Doesn't that take a huge amount of trust?&amp;nbsp; Yeah it does, and that's where I think we need to get.&amp;nbsp; (You can do some more reading on "Agile Contracts" &lt;a href="http://www.infoq.com/news/2007/12/agile-contracts"&gt;here&lt;/a&gt;.)&lt;/p&gt; &lt;p&gt;Incentive based contracts encourage a healthy economy between partners.&amp;nbsp; There's only one goal: to make each-other successful.&amp;nbsp; Now when I come to my partner and ask if it is acceptable to take care of some technical debt, or begin using Test Driven Development, he/she will know that I am only doing it because it is a true investment - and I know that it will benefit me (us!) in the future.&amp;nbsp; &lt;/p&gt; &lt;h2&gt;Less Emphasis On Methodologies&lt;/h2&gt; &lt;p&gt;Agile, Scrum, XP, Waterfall - they all have one thing in common: they don't mean the same thing to any two people.&amp;nbsp; It's all about communication.&amp;nbsp; We have got to stop applying tools to the process by default and instead have one goal in mind: Keep Improving.&amp;nbsp; I think we'll see companies start to understand that in order to manage a software team you have to let the software team do the managing.&amp;nbsp; There are no better people to make management decisions other than your team.&amp;nbsp; They're on the front-lines with the most comprehensive knowledge available, and will always make the best decision possible.&amp;nbsp; &lt;/p&gt; &lt;p&gt;Teams will still require leadership, but leadership should begin to lean more and more on their people to do the critical thinking and solve not only software problems, but also process problems.&amp;nbsp; In summary: More thinking, less blindly applying tools and/or process.&lt;/p&gt; &lt;h2&gt;More Value Placed In Established Software Teams&lt;/h2&gt; &lt;p&gt;It sounds reasonable to believe that a developer is a developer is a developer.&amp;nbsp; You always hear how &lt;em&gt;everyone&lt;/em&gt; is replaceable and we're just all cogs in the wheel.&amp;nbsp; I'd argue that, however.&amp;nbsp; Developers who have built relationships, established trust, and learned strengths and weaknesses will outperform &lt;em&gt;any&lt;/em&gt; other team that has been banded together on-the-fly.&amp;nbsp; Managers and decision makers will eventually begin to see this as they make decisions on who will build their software.&amp;nbsp; Thus you'll see more software teams grow and strengthen and their services will become more valuable. &lt;/p&gt; &lt;h2&gt;Single Responsibility Teams Will Fade&lt;/h2&gt; &lt;p&gt;As people mature in their careers as software developers, skill sets will mature to the point where it will become expected that feature development will occur in a vertical fashion.&amp;nbsp; By this, I mean that each developer on a team should be able to construct a software feature from top (UI) to bottom (Database) with minimal intervention from other developers.&amp;nbsp; There will always be developers with talents that weigh more on user interface design versus skill in SQL Server (for instance), and they will be valuable as team members.&amp;nbsp; But, every team member should have the ability to work independently to provide value to the paying customer.&lt;/p&gt; &lt;h2&gt;Developers Will Provide Their Own Tools&lt;/h2&gt; &lt;p&gt;I've come onto a customer's site on a staff aug contract to be seated at a computer that my mother would have grown frustrated with after using a word processor.&amp;nbsp; This is an edge case for sure, but hopefully it illustrates that our clients don't always understand the need for quality tools.&amp;nbsp; I don't blame them - it's not their area of expertise.&amp;nbsp; We are brought in to fill a need, and we know the most about what we require - so we should be the ones to provide the tools necessary to do the job.&amp;nbsp;&amp;nbsp; There are other trades that require their craftsmen to provide their own tools, take for instance mechanics or construction workers.&amp;nbsp; &lt;/p&gt; &lt;h2&gt;&lt;/h2&gt; &lt;h2&gt;Less Emphasis On Technology, More On the Domain&lt;/h2&gt; &lt;p&gt;We know this: software does not fail to meet customer expectations because of technology.&amp;nbsp; Our first goal shouldn't be to start writing code, but to understand the domain and help our customer make more money.&amp;nbsp; We should be looking at their model and suggesting improvement points.&amp;nbsp; We should be more than the geeks who write code, we should be looked at to solve challenges - technical or otherwise.&amp;nbsp; &lt;/p&gt; &lt;h2&gt;Less Staff Augmentation Consulting&lt;/h2&gt; &lt;p&gt;In a couple of companies that I've consulted for on a staff-aug basis I've seen software systems that were almost literally being held together by duct-tape and paper mache.&amp;nbsp; The observation I made was that the company was hiring contractors almost exclusively and that these hard working people would swoop in, get a cursory understanding of the system, and make patchwork fixes.&amp;nbsp; These fixes were always &lt;em&gt;just good enough&lt;/em&gt; to get the system operational again.&amp;nbsp; And that is probably noble of them because everyone knows that in order to prove you're worth your salt is to be the hero and save the day.&amp;nbsp; This model has got to end.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5996062652829415230-4361188890568164862?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/MSnV5rB7UPM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/4361188890568164862/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=4361188890568164862" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/4361188890568164862?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/4361188890568164862?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/MSnV5rB7UPM/trends-for-my-industry.html" title="Trends For My Industry" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2009/01/trends-for-my-industry.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkEESH8-eip7ImA9WxRUFEo.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-8226830344631326440</id><published>2008-11-23T15:21:00.001-05:00</published><updated>2008-11-23T16:10:09.152-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-23T16:10:09.152-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term="Agile" /><category scheme="http://www.blogger.com/atom/ns#" term="Career" /><title>Agile Elevator Speech</title><content type="html">&lt;p&gt;I've given quite a few "elevator speeches" about &lt;a href="http://www.agilemanifesto.org/"&gt;Agile&lt;/a&gt;.&amp;nbsp; After giving each speech, I've either failed to deliver my message, or my audience failed to understand.&amp;nbsp; &lt;/p&gt; &lt;p&gt;Well, I'm giving up on them.&amp;nbsp; If I can't be successful then I don't want to add to the confusing cacophony of messages about &lt;a href="http://www.agilemanifesto.org/"&gt;Agile&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Stop Advocating?&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;No, I am too passionate about software and software teams to give up advocating Agile.&amp;nbsp; So here is my plan.&lt;/p&gt; &lt;p&gt;I'm going to explain the prizes.&amp;nbsp; It's too hard to explain the tools, so I'll give them the good stuff up front.&lt;/p&gt; &lt;p&gt;Why?&amp;nbsp; Because it's too complex (and important) of a topic to discuss in short time.&amp;nbsp; So in paraphrase here is what I'll tell them:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;When constructing software as a team, I don't care what methodology you're using as long as the team can achieve these goals:&lt;br&gt;&lt;br&gt;1) Fail fast.&lt;br&gt;2) Continuously improve the team.&lt;br&gt;3) Continuously reduce and eliminate waste.&lt;br&gt;4) Indicate (visually or otherwise) the teams progress.&lt;br&gt;5) Embrace change.&lt;/p&gt; &lt;p&gt;Agile happens to have some pretty practical tools that will get us there.&amp;nbsp; If you'd like to join me for lunch, I'd be happy to tell you more!!&lt;/p&gt;&lt;/blockquote&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5996062652829415230-8226830344631326440?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/ox6UCNoplwQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/8226830344631326440/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=8226830344631326440" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/8226830344631326440?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/8226830344631326440?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/ox6UCNoplwQ/agile-elevator-speech.html" title="Agile Elevator Speech" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2008/11/agile-elevator-speech.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIHRHg5eyp7ImA9WxRUEEw.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-3707357223035445643</id><published>2008-11-18T09:07:00.001-05:00</published><updated>2008-11-18T09:12:15.623-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-18T09:12:15.623-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Code Snippet" /><category scheme="http://www.blogger.com/atom/ns#" term="Moq" /><title>Testing Expressions With Moq</title><content type="html">&lt;p&gt;In one of the tests I was writing using &lt;a href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt;, I needed to test that my repository was called with a particular expression.&amp;nbsp; After struggling for a bit, I found a solution which I am sharing here in hopes that it will benefit you.&amp;nbsp; &lt;/p&gt; &lt;div style="font-family: consolas; background: #0f0f0f; color: white; font-size: 10pt"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #ffc66d; font-weight: bold"&gt;Test&lt;/span&gt;]&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #cc7832; font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832; font-weight: bold"&gt;void&lt;/span&gt; Then_Repository_Should_Be_Queried_For_Files_In_Pending_Status()&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #ffc66d; font-weight: bold"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #ffc66d; font-weight: bold"&gt;JSOFile&lt;/span&gt;&amp;gt; dummyFiles = &lt;span style="color: #cc7832; font-weight: bold"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d; font-weight: bold"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #ffc66d; font-weight: bold"&gt;JSOFile&lt;/span&gt;&amp;gt;()&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #cc7832; font-weight: bold"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d; font-weight: bold"&gt;JSOFile&lt;/span&gt;() { STATUS_CD = &lt;span style="color: #86c243; font-weight: bold"&gt;"P"&lt;/span&gt;, FILE_NM = &lt;span style="color: #86c243; font-weight: bold"&gt;"teststring"&lt;/span&gt;},&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #cc7832; font-weight: bold"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d; font-weight: bold"&gt;JSOFile&lt;/span&gt;() { STATUS_CD = &lt;span style="color: #86c243; font-weight: bold"&gt;"Z"&lt;/span&gt;, FILE_NM = &lt;span style="color: #86c243; font-weight: bold"&gt;"test.txt"&lt;/span&gt;}&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 9&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 10&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _repository.Expect(x =&amp;gt; x.FindAll(&lt;span style="color: #ffc66d; font-weight: bold"&gt;It&lt;/span&gt;.IsAny&amp;lt;&lt;span style="color: #ffc66d; font-weight: bold"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: #ffc66d; font-weight: bold"&gt;JSOFile&lt;/span&gt;, &lt;span style="color: #cc7832; font-weight: bold"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt;()))&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 11&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Callback((&lt;span style="color: #ffc66d; font-weight: bold"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: #ffc66d; font-weight: bold"&gt;JSOFile&lt;/span&gt;, &lt;span style="color: #cc7832; font-weight: bold"&gt;bool&lt;/span&gt;&amp;gt; del) =&amp;gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 12&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 13&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dummyFiles = dummyFiles.Where(del).ToList();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 14&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 15&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 16&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _fileManagement = &lt;span style="color: #cc7832; font-weight: bold"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d; font-weight: bold"&gt;FileManagement&lt;/span&gt;(_repository.Object, _logger.Object, _file.Object, _jsoFileReader.Object, _jsoFileParser.Object);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 17&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 18&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _fileManagement.ProcessReceivedFilesToPending();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 19&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 20&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #ffc66d; font-weight: bold"&gt;Assert&lt;/span&gt;.That(dummyFiles.Count == &lt;span style="color: #6897bb; font-weight: bold"&gt;1&lt;/span&gt;, &lt;span style="color: #86c243; font-weight: bold"&gt;"Expression passed into the FindAll method was incorrect."&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 21&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #ffc66d; font-weight: bold"&gt;Assert&lt;/span&gt;.That(dummyFiles.FirstOrDefault().FILE_NM == &lt;span style="color: #86c243; font-weight: bold"&gt;"teststring"&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 22&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 23&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _repository.Verify();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;&amp;nbsp;&amp;nbsp; 24&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&lt;br&gt;&lt;strong&gt;What am I testing?&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;In the method under test (Line 18 _fileManagement.ProcessReceivedFilesToPending()), I want to ensure that my repository is being queried for the appropriate objects.&amp;nbsp; In this case, all "JSOFile" objects with the STATUS_CD of "P".&amp;nbsp; &lt;/p&gt; &lt;p&gt;The meat of this test method is line 10.&amp;nbsp; This line sets up an expectation that the FindAll(Func&amp;lt;JSOFile, bool&amp;gt;) method will be called from the repository object passed in via constructor (line 16, first parameter).&amp;nbsp; &lt;br&gt;&lt;br&gt;(_repository defined as:)&lt;/p&gt; &lt;div style="font-family: consolas; background: #0f0f0f; color: white; font-size: 10pt"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="font-weight: bold"&gt;_repository = &lt;/span&gt;&lt;span style="color: #cc7832; font-weight: bold"&gt;new&lt;/span&gt; Moq.&lt;span style="color: #ffc66d; font-weight: bold"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color: #6897bb; font-weight: bold"&gt;IRepository&lt;/span&gt;&amp;gt;();&lt;/p&gt;&lt;/div&gt; &lt;p&gt;The Expect method takes a lamba expression that allows you to set an expectation on the type being mocked.&amp;nbsp; In addition to setting expectations, you can also define callbacks.&amp;nbsp; In this example, the callback gets fired when the class under test (_fileManagement) executes the mocked object's FindAll() method.&amp;nbsp; Line 13 will receive the delegate that was passed to the _repository.FindAll.&amp;nbsp; To make sure the delegate was what I expected, I execute the delegate against a list of dummy objects.&amp;nbsp; On lines 20 and 21 I make sure that my list was narrowed down to the object with a status of "P".&amp;nbsp; &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Why go to this trouble?&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;In the future if my repository call gets changed, this test will fail and alert the developer that they've broken intended functionality. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5996062652829415230-3707357223035445643?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/7q7gti8WQBY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/3707357223035445643/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=3707357223035445643" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/3707357223035445643?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/3707357223035445643?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/7q7gti8WQBY/testing-expressions-with-moq.html" title="Testing Expressions With Moq" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2008/11/testing-expressions-with-moq.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUFQXk5eCp7ImA9WxRWE0U.&quot;"><id>tag:blogger.com,1999:blog-5996062652829415230.post-2990040753832167103</id><published>2008-10-30T13:20:00.001-04:00</published><updated>2008-10-30T13:20:10.720-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-30T13:20:10.720-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Code Snippet" /><category scheme="http://www.blogger.com/atom/ns#" term="CSS" /><category scheme="http://www.blogger.com/atom/ns#" term="Annoyance" /><title>Internet Explorer CSS Quirk (border-spacing)</title><content type="html">&lt;p&gt;Consider the following CSS class:&lt;/p&gt; &lt;p&gt;.test&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; border-spacing: 0px; /*Only works in Firefox */&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; border-collapse: collapse;&amp;nbsp;&amp;nbsp;&amp;nbsp; /*Works in Firefox and IE */&lt;br&gt;} &lt;p&gt;With the border spacing CSS style attribute set to zero pixels, Firefox and IE render differently:&lt;/p&gt; &lt;p&gt;Internet Explorer:&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_KdHZl3mpBzc/SQnsxZ21lII/AAAAAAAAAlM/UsYwb50Z7Ok/s1600-h/ie%5B4%5D.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="ie" src="http://lh5.ggpht.com/_KdHZl3mpBzc/SQnsx7UsyBI/AAAAAAAAAlQ/e83f9c8nuTs/ie_thumb%5B2%5D.gif?imgmax=800" width="484" height="277"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Firefox: &lt;/p&gt; &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_KdHZl3mpBzc/SQnsyDV4KxI/AAAAAAAAAlU/JCFyCssX9Q0/s1600-h/firefox%5B4%5D.gif"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="firefox" src="http://lh6.ggpht.com/_KdHZl3mpBzc/SQnsyrdmD6I/AAAAAAAAAlY/Hj5vhT9HhEk/firefox_thumb%5B2%5D.gif?imgmax=800" width="510" height="260"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;br&gt;Moral: Use "border-collapse: collapse;" when you want no border spacing in your tables. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5996062652829415230-2990040753832167103?l=blog.stevehorn.cc' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/foremanbob/~4/5fOmw_P-3YM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.stevehorn.cc/feeds/2990040753832167103/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5996062652829415230&amp;postID=2990040753832167103" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/2990040753832167103?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5996062652829415230/posts/default/2990040753832167103?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/foremanbob/~3/5fOmw_P-3YM/internet-explorer-css-quirk-border.html" title="Internet Explorer CSS Quirk (border-spacing)" /><author><name>Steve Horn</name><uri>http://www.blogger.com/profile/11799829988971859359</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="09154138260003946301" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.stevehorn.cc/2008/10/internet-explorer-css-quirk-border.html</feedburner:origLink></entry></feed>
