<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>try-catch-FAIL</title>
    <description>Failure is inevitable</description>
    <link>http://trycatchfail.com/blog/</link>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>BlogEngine.NET 1.6.1.0</generator>
    <language>en-US</language>
    <blogChannel:blogRoll>http://trycatchfail.com/blog/opml.axd</blogChannel:blogRoll>
    <blogChannel:blink>http://www.dotnetblogengine.net/syndication.axd</blogChannel:blink>
    <dc:creator>Matt Honeycutt</dc:creator>
    <dc:title>try-catch-FAIL</dc:title>
    <geo:lat>0.000000</geo:lat>
    <geo:long>0.000000</geo:long>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Try-catch-fail" /><feedburner:info uri="try-catch-fail" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.0/</creativeCommons:license><item>
      <title>A View Engine for ASP.NET MVC Feature-Based Organized</title>
      <description>&lt;p&gt;I am a huge fan of ASP.NET MVC.&amp;#160; It is leaps and bounds ahead of WebForms, and if you’re doing web development on the Microsoft platform, it’s arguably the best overall solution available.&amp;#160; But it is far from perfect.&amp;#160; One of the things that has bugged me about it since the very beginning is the default organization conventions, meaning separate folders for controllers, view models, and views.&amp;#160; These conventions can be replaced though.&amp;#160; Read on to see how.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h2&gt;The Default Conventions&lt;/h2&gt;  &lt;p&gt;If you create a new MVC project using the typical File –&amp;gt; New Project approach, you’re going to end up with something that looks like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://trycatchfail.com/blog/image.axd?picture=image_68.png"&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://trycatchfail.com/blog/image.axd?picture=image_thumb_68.png" width="316" height="476" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Your controllers go in one folder, your views in another, and your models in yet another folder.&amp;#160; I suppose one could come up with a worse way to organize things, but you’d have to work at it a bit.&amp;#160; This approach is akin to creating separate folders for classes, interfaces, enums, etc.&amp;#160; Type-based organization flies in the face of good design principles.&amp;#160; The Common Closure Principle doesn’t exactly fit here, but I believe the intent does.&amp;#160; Instead of organizing by type, I much prefer to organize things by &lt;em&gt;feature&lt;/em&gt;, with all the files that are involved in a feature living as close to one another as is possible.&amp;#160; Why, you ask?&amp;#160; Things that are likely to change together should live close together because it makes navigating (and therefore maintaining) the code much simpler.&amp;#160; I don’t want to bounce around between three or four folders while trying to implement a feature, nor hunt around to see where something is used.&amp;#160; Instead, I want everything that is related, everything that I should have in my mental context, in one convenient location.&amp;#160;&amp;#160; I don’t want 50 controllers to weed through, I want to see the one controller that implements the feature I’m working on.&amp;#160; I don’t want 100 view folders to scan, I want to see the relevant views sitting right beside my controller.&amp;#160; Everything else is just noise.&lt;/p&gt;  &lt;p&gt;But, that’s not how MVC works.&amp;#160; Out of the box it wants you to have separate folders for each type, with the implementation of each feature spread all across your project. Areas can help a bit with clutter and organization, and Visual Studio and many of the other productivity tools out there try to alleviate some of this pain by making it easy to bounce around, but the core of the problem is still there: we should organize by feature, not by type.&amp;#160; Fortunately this is actually quite doable.&amp;#160; &lt;/p&gt;  &lt;h2&gt;A Custom ViewEngine&lt;/h2&gt;  &lt;p&gt;ASP.NET MVC will actually let us put our controllers wherever we want.&amp;#160; As long as it implements IController, we can define routes to it.&amp;#160; And models can also live wherever we want.&amp;#160; The problem is the views.&amp;#160; The default convention is to resolve views using something like “~/Views/{Controller}/{Action}.”&amp;#160;&amp;#160; It’s a little more complex than that, but not by much.&amp;#160; What I’d &lt;em&gt;like&lt;/em&gt; is a convention that supports this type of layout:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://trycatchfail.com/blog/image.axd?picture=image_69.png"&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://trycatchfail.com/blog/image.axd?picture=image_thumb_69.png" width="387" height="499" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Notice how everything related to logging in is in the same place: the controller, the models, and the views.&amp;#160; I can ignore everything outside of this scope because it isn’t relevant to the feature.&amp;#160; &lt;/p&gt;  &lt;p&gt;We can take a naïve approach and swap this convention in easily enough, enabling us to do something like “~/Features/{Controller}/{Action}.” &lt;a href="http://gurustop.net/blog/2012/09/11/aspnetmvc4-application-structure-by-features-move-views-by-area/" target="_blank"&gt;Here’s an example from Mohamed Meligy&lt;/a&gt;.&amp;#160; This approach somewhat works, but it will break down if we ever have a feature folder whose name doesn’t match 1-to-1 with the corresponding controller.&amp;#160; And that’s going to happen the first time you have two controllers related to the same feature.&amp;#160; Instead, assuming we keep our folder names and namespaces in sync, we can take a more robust approach and use the namespace of the controller to locate a corresponding “Views” folder: &lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;public class FolderPerFeatureConventionViewEngine : RazorViewEngine
{
    //This needs to be initialized to the root namespace of your MVC project.
    //Usually, the namespace of your Global.asax's codebehind will do the trick.
    private static readonly string RootNamespace = typeof (MvcApplication).Namespace;

    private static string GetPath(ControllerContext controllerContext, string viewName)
    {
        //TODO: Cache?
        var controllerType = controllerContext.Controller.GetType();
        var featureFolder = &amp;quot;~&amp;quot; + controllerType.Namespace.Replace(RootNamespace, string.Empty).Replace(&amp;quot;.&amp;quot;, &amp;quot;/&amp;quot;);

        var path = featureFolder + &amp;quot;/Views/&amp;quot; + viewName + &amp;quot;.cshtml&amp;quot;;
        return path;
    }

    public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
    {
        var path = GetPath(controllerContext, viewName);

        if (VirtualPathProvider.FileExists(path))
        {
            return new ViewEngineResult(CreateView(controllerContext, path, null), this);
        }
        else
        {
            return new ViewEngineResult(new[] {path});
        }
    }

    public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
    {
        var path = GetPath(controllerContext, partialViewName);

        if (VirtualPathProvider.FileExists(path))
        {
            return new ViewEngineResult(CreateView(controllerContext, path, null), this);
        }
        else
        {
            return new ViewEngineResult(new[] { path });
        }
    }
}&lt;/pre&gt;

&lt;p&gt;Another nice benefit of this approach is that it negates the need for areas.&amp;#160; I can now organize my features however I want, keeping related files packaged together, and avoid the complexity that comes with areas. &lt;/p&gt;

&lt;h2&gt;Future Work&lt;/h2&gt;

&lt;p&gt;This code is definitely not production-tested.&amp;#160; I threw it together quickly, and I’m quite sure there are holes in it.&amp;#160; It could also benefit from some caching.&amp;#160; If you take this and extend it, please let me know, and I will update this post with any improvements that are made. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Try-catch-fail/~4/zoOMoCJ5TJY" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Try-catch-fail/~3/zoOMoCJ5TJY/post.aspx</link>
      <author>Matt</author>
      <comments>http://trycatchfail.com/blog/post/A-View-Engine-for-ASPNET-MVC-Feature-Based-Organized.aspx#comment</comments>
      <guid isPermaLink="false">http://trycatchfail.com/blog/post.aspx?id=06e92f38-5ec7-4190-bf67-a76fff8ab1d5</guid>
      <pubDate>Mon, 29 Apr 2013 11:25:38 -1300</pubDate>
      <category>MVC</category>
      <category>ASP.NET</category>
      <dc:publisher>Matt</dc:publisher>
      <pingback:server>http://trycatchfail.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://trycatchfail.com/blog/post.aspx?id=06e92f38-5ec7-4190-bf67-a76fff8ab1d5</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://trycatchfail.com/blog/trackback.axd?id=06e92f38-5ec7-4190-bf67-a76fff8ab1d5</trackback:ping>
      <wfw:comment>http://trycatchfail.com/blog/post/A-View-Engine-for-ASPNET-MVC-Feature-Based-Organized.aspx#comment</wfw:comment>
      <wfw:commentRss>http://trycatchfail.com/blog/syndication.axd?post=06e92f38-5ec7-4190-bf67-a76fff8ab1d5</wfw:commentRss>
    <feedburner:origLink>http://trycatchfail.com/blog/post.aspx?id=06e92f38-5ec7-4190-bf67-a76fff8ab1d5</feedburner:origLink></item>
    <item>
      <title>SpecsFor V3.0 FINAL Finally Available, Finally!</title>
      <description>&lt;p&gt;Well, that certainly took long enough.&amp;#160; It’s been nearly a year since I &lt;a href="http://trycatchfail.com/blog/post/Musings-on-SpecsFor-30.aspx" target="_blank"&gt;first blogged about SpecsFor 3.0&lt;/a&gt;, but I just pushed the final version to NuGet a short while ago. &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;This release includes a few breaking changes, but for the most part your tests that were created with &lt;a href="http://specsfor.com/" target="_blank"&gt;SpecsFor&lt;/a&gt; V2 should continue to work exactly the same as before.&amp;#160; Here’s a quick rundown of the changes:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Breaking Change &lt;/strong&gt;– AfterEachSpec renamed to AfterEachTest – This change was made to better reflect when the callback is actually run: after each individual test case.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Breaking Change &lt;/strong&gt;– AfterSpec callback method added –&amp;#160; You can use this to run any final cleanup after all the tests within a spec have executed.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Breaking Change &lt;/strong&gt;– Attribute-based method of applying context removed completely –&amp;#160; This feature was seldom used from what I can tell, ill-conceived to begin with, and not properly supported by some popular test runners (I’m looking at you, Resharper). &lt;/li&gt;    &lt;li&gt;Composable Context System – You can now define standalone behaviors that will be applied to your specs based on conventions you specify.&amp;#160; Create a &lt;a href="http://www.nunit.org/index.php?p=setupFixture&amp;amp;r=2.5" target="_blank"&gt;SetUpFixture&lt;/a&gt; derived from SpecsForConfiguration to get started.&lt;/li&gt;    &lt;li&gt;New extension methods – There are some new methods to help with testing.&amp;#160; I’ll run through these in an upcoming post.&lt;/li&gt;    &lt;li&gt;Complete internal rewrite – I was never happy with the SpecsFor base class.&amp;#160; It started off with too many responsibilities, and it only grew with each release.&amp;#160; I’ve refactored and simplified things while doing my best to preserve compatibility with existing tests.&amp;#160; Let me know if I failed. :)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In the coming weeks (or months?) I’ll go in-depth with each of these changes here on this blog.&amp;#160; I’ll also get the main site updated with better docs and examples.&amp;#160; If anyone would like to help, please let me know.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Try-catch-fail/~4/53-LYMOH6fo" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Try-catch-fail/~3/53-LYMOH6fo/post.aspx</link>
      <author>Matt</author>
      <comments>http://trycatchfail.com/blog/post/SpecsFor-V30-FINAL-Finally-Available-Finally!.aspx#comment</comments>
      <guid isPermaLink="false">http://trycatchfail.com/blog/post.aspx?id=80d19cdb-5e5c-46ef-bb4e-a32a8da13342</guid>
      <pubDate>Thu, 07 Mar 2013 16:54:56 -1300</pubDate>
      <category>SpecsFor</category>
      <dc:publisher>Matt</dc:publisher>
      <pingback:server>http://trycatchfail.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://trycatchfail.com/blog/post.aspx?id=80d19cdb-5e5c-46ef-bb4e-a32a8da13342</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://trycatchfail.com/blog/trackback.axd?id=80d19cdb-5e5c-46ef-bb4e-a32a8da13342</trackback:ping>
      <wfw:comment>http://trycatchfail.com/blog/post/SpecsFor-V30-FINAL-Finally-Available-Finally!.aspx#comment</wfw:comment>
      <wfw:commentRss>http://trycatchfail.com/blog/syndication.axd?post=80d19cdb-5e5c-46ef-bb4e-a32a8da13342</wfw:commentRss>
    <feedburner:origLink>http://trycatchfail.com/blog/post.aspx?id=80d19cdb-5e5c-46ef-bb4e-a32a8da13342</feedburner:origLink></item>
    <item>
      <title>SpecsFor V3 Release Candidate Now Available</title>
      <description>&lt;p&gt;The SpecsFor 3.0 release is nearing completion!&amp;#160; The release candidate is now on NuGet.&amp;#160; This release further cleans up and simplifies things and lays the groundwork for porting &lt;a href="http://specsfor.com/" target="_blank"&gt;SpecsFor&lt;/a&gt; to other testing frameworks.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;To try out the release candidate, install the prerelease version from NuGet:&lt;/p&gt; &lt;style type="text/css"&gt;







.commandwrapper
{
	background: #d6d6d6;
	border: 0px solid white;
	padding: 4px;
	margin: 36px 0;
	filter: progid:dximagetransform.microsoft.gradient(gradienttype=0, startcolorstr='#d6d6d6', endcolorstr='#505050');
	background: -webkit-gradient(linear, 0 0, 0 100%, from(#d6d6d6), to(#505050));
	background: -moz-linear-gradient(top, #d6d6d6, #505050);
	border-radius: 8px;
	-webkit-border-radius: 8px;
	-moz-border-radius: 8px;
}
		
.commandprompt
{
	background: black;
	border: 1px solid #c4c4c4;
	text-shadow: 1px 1px 1px rgba(0, 0, 0, 1.0);
	filter: progid:dximagetransform.microsoft.gradient(gradienttype=0, startcolorstr='#5e5e5e', endcolorstr='#000');
	background: -webkit-gradient(linear, 0 0, 0 100%, from(#5e5e5e), to(black));
	background: -moz-linear-gradient(top, #5e5e5e, black);
	box-shadow: inset 6px 6px 14px rgba(0, 0, 0, 0.6), 1px 1px 4px rgba(102, 102, 102, 1.0);
	-webkit-box-shadow: inset 6px 6px 14px rgba(0, 0, 0, 0.6), 1px 1px 4px rgba(102, 102, 102, 1.0);
	-moz-box-shadow: inset 6px 6px 14px rgba(0, 0, 0, 0.6), 1px 1px 4px rgba(102, 102, 102, 1.0);
	border-radius: 6px;
	-webkit-border-radius: 6px;
	-moz-border-radius: 6px;
}
		
.command
{
	color: #72eb18;
	color: #e2e2e2;
	font-family: consolas, "Andale Mono WT" , "Andale Mono" , "Lucida Console" , "Lucida Sans Typewriter" , "DejaVu Sans Mono" , "Bitstream Vera Sans Mono" , "Liberation Mono" , "Nimbus Mono L" , monaco, "Courier New" , courier, monospace;
	font-size: 24px;
	line-height: 24px;
	margin: 24px 8px;
}&lt;/style&gt;  &lt;div class="commandwrapper"&gt;   &lt;div class="commandprompt"&gt;     &lt;p class="command"&gt;PM&amp;gt; Install-Package SpecsFor -Pre&lt;/p&gt;   &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;Since the last preview release, I gutted and rewrote the entire core.&amp;#160; This allowed me to drastically improve test coverage of the core itself and will make it possible to reuse much of the code for other testing frameworks (SpecsFor.MsTest, anyone?)&lt;/p&gt;  &lt;p&gt;For more about the changes in 3.0, check out my &lt;a href="http://trycatchfail.com/blog/post/SpecsFor-30-Preview-Available-on-NuGet.aspx" target="_blank"&gt;previous post&lt;/a&gt;. &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Try-catch-fail/~4/1_pQUjqmPRw" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Try-catch-fail/~3/1_pQUjqmPRw/post.aspx</link>
      <author>Matt</author>
      <comments>http://trycatchfail.com/blog/post/SpecsFor-V3-Release-Candidate-Now-Available.aspx#comment</comments>
      <guid isPermaLink="false">http://trycatchfail.com/blog/post.aspx?id=a05b9541-d703-4455-9031-6af637591303</guid>
      <pubDate>Mon, 25 Feb 2013 13:21:39 -1300</pubDate>
      <category>SpecsFor</category>
      <category>Testing</category>
      <dc:publisher>Matt</dc:publisher>
      <pingback:server>http://trycatchfail.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://trycatchfail.com/blog/post.aspx?id=a05b9541-d703-4455-9031-6af637591303</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://trycatchfail.com/blog/trackback.axd?id=a05b9541-d703-4455-9031-6af637591303</trackback:ping>
      <wfw:comment>http://trycatchfail.com/blog/post/SpecsFor-V3-Release-Candidate-Now-Available.aspx#comment</wfw:comment>
      <wfw:commentRss>http://trycatchfail.com/blog/syndication.axd?post=a05b9541-d703-4455-9031-6af637591303</wfw:commentRss>
    <feedburner:origLink>http://trycatchfail.com/blog/post.aspx?id=a05b9541-d703-4455-9031-6af637591303</feedburner:origLink></item>
    <item>
      <title>Connecting TeamCity to Gitblit</title>
      <description>&lt;p&gt;This post is more of a reference for myself than anything else, but you might find it useful if you have run into security problems while trying to hook TeamCity to a Gitblit server that uses a self-signed certificate.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;My team is slowly migrating to &lt;a href="http://gitblit.com/"&gt;Gitblit&lt;/a&gt; from Subversion.&amp;#160; We’re big on Continuous Integration, so we had to get TeamCity talking with our Gitblit server.&amp;#160; This turned out to be a lot more painful than you might think.&amp;#160; Gitblit installs with a self-signed certificate.&amp;#160; While you should, in theory, be able to swap in a trusted cert purchased from a trusted authority, we were unable to get it to work.&amp;#160; So, we are stuck with the self-signed cert.&amp;#160; Not the end of the world, but not ideal.&lt;/p&gt;  &lt;p&gt;Anyway, the next hurdle was getting TeamCity to communicate with Gitblit.&amp;#160; Because we were using an untrusted certificate, we ran into the following exception:&lt;/p&gt;  &lt;p&gt;javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target&lt;/p&gt;  &lt;p&gt;After a little digging and with some help from &lt;a href="http://solveme.wordpress.com/2008/12/10/javax-net-ssl-sslhandshakeexception/"&gt;this post&lt;/a&gt;, I got things working. &lt;/p&gt;  &lt;p&gt;First, export the certificate from Gitbit.&amp;#160; The easiest way to do this is to navigate to your Gitblit site in Chrome, click the security icon by the URL, change the “Connection” tab, then click “Certificate information.”&lt;/p&gt;  &lt;p&gt;&lt;a href="http://trycatchfail.com/blog/image.axd?picture=image_67.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://trycatchfail.com/blog/image.axd?picture=image_thumb_67.png" width="244" height="162" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This will open a Certificate details window.&amp;#160; Change to the “Details” tab, then click “Copy to File” to save the certificate to your computer.&amp;#160; &lt;/p&gt;  &lt;p&gt;Next, open a Powershell prompt on your build server, and go to your TeamCity installation folder.&amp;#160; For our build server, this was c:\TeamCity.&amp;#160; In here you will have a “jre” folder where TeamCity installed the Java runtime it uses for hosting the web server and build agent.&amp;#160; Copy the certificate you extracted from Gitblit to this same folder, then run the following command:&lt;/p&gt;  &lt;pre class="brush: ps;"&gt;.\bin\keytool.exe -import -alias git.yourservername.com -file yourcertificate.cer -keystore lib\security\cacerts&lt;/pre&gt;

&lt;p&gt;When prompted for a password, enter ‘changeit”.&amp;#160; Yep, that’s the default password.&amp;#160; This will install the certificate into the cacerts keystore (note: if you get a permissions error, try granting your Windows account full permission to the file). After a restart, TeamCity should now be able to connect to your Gitblit server!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Try-catch-fail/~4/jSpuUJWtMdE" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Try-catch-fail/~3/jSpuUJWtMdE/post.aspx</link>
      <author>Matt</author>
      <comments>http://trycatchfail.com/blog/post/Connecting-TeamCity-to-Gitblit.aspx#comment</comments>
      <guid isPermaLink="false">http://trycatchfail.com/blog/post.aspx?id=4d7fbba5-1d8e-4889-a579-aeb62512175a</guid>
      <pubDate>Tue, 12 Feb 2013 06:11:47 -1300</pubDate>
      <category>git</category>
      <dc:publisher>Matt</dc:publisher>
      <pingback:server>http://trycatchfail.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://trycatchfail.com/blog/post.aspx?id=4d7fbba5-1d8e-4889-a579-aeb62512175a</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://trycatchfail.com/blog/trackback.axd?id=4d7fbba5-1d8e-4889-a579-aeb62512175a</trackback:ping>
      <wfw:comment>http://trycatchfail.com/blog/post/Connecting-TeamCity-to-Gitblit.aspx#comment</wfw:comment>
      <wfw:commentRss>http://trycatchfail.com/blog/syndication.axd?post=4d7fbba5-1d8e-4889-a579-aeb62512175a</wfw:commentRss>
    <feedburner:origLink>http://trycatchfail.com/blog/post.aspx?id=4d7fbba5-1d8e-4889-a579-aeb62512175a</feedburner:origLink></item>
    <item>
      <title>A Generic Entity Framework 5 Repository With Eager-Loading</title>
      <description>&lt;p&gt;I’ve been doing some work with Entity Framework 5 lately.&amp;#160; Here’s a simple generic repository I created that allows you to “Include” related entities by applying an attribute.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Consider these sample entities:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;public class User
{
    [Key]
    public int UserId { get; set; }

    [Required, MaxLength(50)]
    public string Username { get; set; }

    [Required]
    public UserDetails Details { get; set; }

    [Required]
    public SecurityQuestions SecurityQuestion { get; set; }

    [Required, MaxLength(50)]
    public string SecurityAnswer { get; set; }

    [Required]
    public RegisterStatus RegisterStatus { get; set; }
}

public class UserDetails
{
    [Key]
    public int UserId { get; set; }
    [ForeignKey(&amp;quot;UserId&amp;quot;)]
    public virtual User User { get; set; }

    [Required]
    public int AddressId { get; set; }
    [ForeignKey(&amp;quot;AddressId&amp;quot;)]
    public Address Address { get; set; }

    [Required, MaxLength(50)]
    public string FirstName { get; set; }

    [Required, MaxLength(80)]
    public string LastName { get; set; }

    [Required, MaxLength(20)]
    public string Phone { get; set; }

    [Required, MaxLength(100)]
    public string Email { get; set; }

    public bool IsDeleted { get; set; }
}

public class Address
{
    [Key]
    public int AddressId { get; set; }

    [Required, MaxLength(120)]
    public string Address1 { get; set; }

    [Required, MaxLength(120)]
    public string City { get; set; }

    [Required, MaxLength(3)]
    public string State { get; set; }

    [Required, MaxLength(20)]
    public string Zip { get; set; }

    public double Longitude { set; get; }

    public double Latitude { set; get; }
}&lt;/pre&gt;

&lt;p&gt;There’s a simple one-to-one relationship between a User and UserDetails, and a one-to-one relationship from a UserDetails to Address.&amp;#160; With Entity Framework Code-First’s out-of-the-box configuration, the User.Details property will &lt;strong&gt;not&lt;/strong&gt; be loaded with it’s parent User object.&amp;#160; Neither will the UserDetails.Address property.&amp;#160; EF provides the &lt;a href="http://msdn.microsoft.com/en-us/library/gg696785(v=vs.103).aspx" target="_blank"&gt;Include&lt;/a&gt; method to specify which related entities to pull in when you make a query, but the whole point of a generic repository is that it doesn’t truly know about the entity it contains.&amp;#160; We could expose the Include method through the repository, but that’s pretty ugly and is just one more thing we have to think about when utilizing the repository.&amp;#160; We could also take advantage of lazy-loading by making the properties virtual, but for simple one-to-one relationships, lazy-loading could result in unnecessary roundtrips to the database.&amp;#160; &lt;/p&gt;

&lt;p&gt;Instead, I created a simple marker attribute called “Include.”&amp;#160; When applied to a property, it instructs the generic repository to include that property when it retrieves the parent object.&amp;#160; Here’s the repository:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class Repository&amp;lt;TEntity&amp;gt; : IRepository&amp;lt;TEntity&amp;gt; where TEntity : class
{
    private static readonly PropertyIncluder&amp;lt;TEntity&amp;gt; Includer = new PropertyIncluder&amp;lt;TEntity&amp;gt;();

    private readonly DbSet&amp;lt;TEntity&amp;gt; _dbSet;
    private readonly RecRentContext _context;

    public Repository(RecRentContext context)
    {
        _dbSet = context.Set&amp;lt;TEntity&amp;gt;();
        _context = context;
    }

    public void Add(TEntity entity)
    {
        _dbSet.Add(entity);
    }

    public void Update(TEntity entity)
    {
        _context.Entry(entity).State = EntityState.Modified;
    }

    public void Delete(object id)
    {
        Delete(_dbSet.Find(id));
    }

    public void Delete(TEntity entity)
    {
        if (_context.Entry(entity).State == EntityState.Detached)
        {
            _dbSet.Attach(entity);
        }

        _dbSet.Remove(entity);
    }

    public IQueryable&amp;lt;TEntity&amp;gt; Query()
    {
        return Includer.BuildQuery(_dbSet);
    }
}&lt;/pre&gt;

&lt;p&gt;And here’s the PropertyIncluder, which creates and caches a method to apply the appropriate Include calls at runtime:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class PropertyIncluder&amp;lt;TEntity&amp;gt; where TEntity : class
{
    private readonly Func&amp;lt;DbQuery&amp;lt;TEntity&amp;gt;, DbQuery&amp;lt;TEntity&amp;gt;&amp;gt;  _includeMethod;
    private readonly HashSet&amp;lt;Type&amp;gt; _visitedTypes;

    public PropertyIncluder()
    {
        //Recursively get properties to include
        _visitedTypes = new HashSet&amp;lt;Type&amp;gt;();
        var propsToLoad = GetPropsToLoad(typeof (TEntity)).ToArray();

        _includeMethod = d =&amp;gt;
        {
            var dbSet = d;
            foreach (var prop in propsToLoad)
            {
                dbSet = dbSet.Include(prop);
            }

            return dbSet;
        };
    }

    private IEnumerable&amp;lt;string&amp;gt; GetPropsToLoad(Type type)
    {
        _visitedTypes.Add(type);
        var propsToLoad = type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                                          .Where(p =&amp;gt; p.GetCustomAttributes(typeof (IncludeAttribute), true).Any());

        foreach (var prop in propsToLoad)
        {
            yield return prop.Name;

            if (_visitedTypes.Contains(prop.PropertyType))
                continue;

            foreach (var subProp in GetPropsToLoad(prop.PropertyType))
            {
                yield return prop.Name + &amp;quot;.&amp;quot; + subProp;
            }
        }
    }

    public DbQuery&amp;lt;TEntity&amp;gt; BuildQuery(DbSet&amp;lt;TEntity&amp;gt; dbSet)
    {
        return _includeMethod(dbSet);
    }
}&lt;/pre&gt;

&lt;p&gt;This approach does utilize reflection, but since it caches the method it creates, you only pay a small penalty during application startup.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Try-catch-fail/~4/KPtdZ4oOy44" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Try-catch-fail/~3/KPtdZ4oOy44/post.aspx</link>
      <author>Matt</author>
      <comments>http://trycatchfail.com/blog/post/A-Generic-Entity-Framework-5-Repository-With-Eager-Loading.aspx#comment</comments>
      <guid isPermaLink="false">http://trycatchfail.com/blog/post.aspx?id=37d1cbce-4b70-4e96-9ea6-41dee6eb12b4</guid>
      <pubDate>Sat, 02 Feb 2013 08:56:26 -1300</pubDate>
      <category>EntityFramework</category>
      <dc:publisher>Matt</dc:publisher>
      <pingback:server>http://trycatchfail.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://trycatchfail.com/blog/post.aspx?id=37d1cbce-4b70-4e96-9ea6-41dee6eb12b4</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://trycatchfail.com/blog/trackback.axd?id=37d1cbce-4b70-4e96-9ea6-41dee6eb12b4</trackback:ping>
      <wfw:comment>http://trycatchfail.com/blog/post/A-Generic-Entity-Framework-5-Repository-With-Eager-Loading.aspx#comment</wfw:comment>
      <wfw:commentRss>http://trycatchfail.com/blog/syndication.axd?post=37d1cbce-4b70-4e96-9ea6-41dee6eb12b4</wfw:commentRss>
    <feedburner:origLink>http://trycatchfail.com/blog/post.aspx?id=37d1cbce-4b70-4e96-9ea6-41dee6eb12b4</feedburner:origLink></item>
    <item>
      <title>SpecsFor 3.0 Preview Available on NuGet</title>
      <description>&lt;p&gt;The first preview release of &lt;a href="http://specsfor.com/" target="_blank"&gt;SpecsFor&lt;/a&gt; 3.0 is now available on NuGet.&amp;#160; This release cleans up and simplifies much of the core while dropping some ill-conceived features, but it also adds a brand new system for composing test context. &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;To try out the new releases, install the prerelease version from NuGet:&lt;/p&gt; &lt;style type="text/css"&gt;






.commandwrapper
{
	background: #d6d6d6;
	border: 0px solid white;
	padding: 4px;
	margin: 36px 0;
	filter: progid:dximagetransform.microsoft.gradient(gradienttype=0, startcolorstr='#d6d6d6', endcolorstr='#505050');
	background: -webkit-gradient(linear, 0 0, 0 100%, from(#d6d6d6), to(#505050));
	background: -moz-linear-gradient(top, #d6d6d6, #505050);
	border-radius: 8px;
	-webkit-border-radius: 8px;
	-moz-border-radius: 8px;
}
		
.commandprompt
{
	background: black;
	border: 1px solid #c4c4c4;
	text-shadow: 1px 1px 1px rgba(0, 0, 0, 1.0);
	filter: progid:dximagetransform.microsoft.gradient(gradienttype=0, startcolorstr='#5e5e5e', endcolorstr='#000');
	background: -webkit-gradient(linear, 0 0, 0 100%, from(#5e5e5e), to(black));
	background: -moz-linear-gradient(top, #5e5e5e, black);
	box-shadow: inset 6px 6px 14px rgba(0, 0, 0, 0.6), 1px 1px 4px rgba(102, 102, 102, 1.0);
	-webkit-box-shadow: inset 6px 6px 14px rgba(0, 0, 0, 0.6), 1px 1px 4px rgba(102, 102, 102, 1.0);
	-moz-box-shadow: inset 6px 6px 14px rgba(0, 0, 0, 0.6), 1px 1px 4px rgba(102, 102, 102, 1.0);
	border-radius: 6px;
	-webkit-border-radius: 6px;
	-moz-border-radius: 6px;
}
		
.command
{
	color: #72eb18;
	color: #e2e2e2;
	font-family: consolas, "Andale Mono WT" , "Andale Mono" , "Lucida Console" , "Lucida Sans Typewriter" , "DejaVu Sans Mono" , "Bitstream Vera Sans Mono" , "Liberation Mono" , "Nimbus Mono L" , monaco, "Courier New" , courier, monospace;
	font-size: 24px;
	line-height: 24px;
	margin: 24px 8px;
}&lt;/style&gt;  &lt;div class="commandwrapper"&gt;   &lt;div class="commandprompt"&gt;     &lt;p class="command"&gt;PM&amp;gt; Install-Package SpecsFor -Pre&lt;/p&gt;   &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;Be warned that there are several breaking changes in this preview release.&amp;#160; Here is (I think) a full list:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;ITestState renamed to ISpecs. &lt;/li&gt;    &lt;li&gt;Attribute-based method of specifying context completely removed. &lt;/li&gt;    &lt;li&gt;Given&amp;lt;TContext&amp;gt; and Given(TContext) methods now execute immediately when called.&amp;#160; You no longer have to remember to call base.Given(). &lt;/li&gt;    &lt;li&gt;AfterEachSpec renamed to AfterSpec to alleviate some confusion about when it is executed. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;If you find something else that doesn’t work after upgrade, please let me know.&amp;#160; I hate breaking changes, but I feel like these changes are necessary to help SpecsFor grow.&amp;#160; Overall, the spec lifecycle is a little cleaner and simpler now with fewer “gotchas” waiting in the wings (such as registering context with Given&amp;lt;TContext&amp;gt; but then forgetting to call base.Given to trigger its execution).&lt;/p&gt;  &lt;p&gt;There are lots of enhancements in this release, the biggest of which is what I’m calling “Composable Context.”&amp;#160; Composable Context allows you to do things like this:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;[SetUpFixture]
public class ComposingContextConfig : SpecsForConfiguration
{
    public ComposingContextConfig()
    {
        WhenTesting&amp;lt;ILikeMagic&amp;gt;().EnrichWith&amp;lt;ProvideMagicByInterface&amp;gt;();
        WhenTesting&amp;lt;SpecsFor&amp;lt;Widget&amp;gt;&amp;gt;().EnrichWith&amp;lt;ProvideMagicByConcreteType&amp;gt;();
        WhenTesting(t =&amp;gt; t.Name.Contains(&amp;quot;running_tests_decorated&amp;quot;)).EnrichWith&amp;lt;ProvideMagicByTypeName&amp;gt;();
        WhenTesting(t =&amp;gt; t.Name.Contains(&amp;quot;junk that does not exist&amp;quot;)).EnrichWith&amp;lt;DoNotProvideMagic&amp;gt;();
        WhenTestingAnything().EnrichWith&amp;lt;ProvideMagicForEveryone&amp;gt;();
        WhenTestingAnything().EnrichWith&amp;lt;MyTestLogger&amp;gt;();
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Note: full code is available on the &lt;a href="https://github.com/MattHoneycutt/SpecsFor/" target="_blank"&gt;Github repo&lt;/a&gt;. &lt;/em&gt;&lt;/p&gt;

&lt;p&gt;These conventions are applied only to tests located within the same namespace as the configuration class or within one of its child namespaces.&amp;#160; Composable Context stacks up, too, meaning you can have multiple layers of conventions.&lt;/p&gt;

&lt;p&gt;What is Composable Context good for?&amp;#160; One possible use is database integration testing:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;[SetUpFixture]
public class DatabaseConfig : SpecsForConfiguration
{
    public ComposingContextConfig()
    {
        WhenTestingAnything().EnrichWith&amp;lt;TransactionScopeWrapper&amp;gt;();
        WhenTesting&amp;lt;IRequireDatabase&amp;gt;().EnrichWith&amp;lt;DatabaseFactoryContext&amp;gt;();
    }
}&lt;/pre&gt;

&lt;p&gt;With this approach, all specs are automatically wrapped in a TransactionScope, while tests that need access to a database need only implement an interface. &lt;/p&gt;

&lt;h2&gt;Feedback Is Welcome&lt;/h2&gt;

&lt;p&gt;I would love to hear what others think.&amp;#160; I bounced back and forth for quite a while before settling on the changes in this version, and there are many pieces that I’m still not 100% sold on.&amp;#160; This is a preview release.&amp;#160; This is not the official 3.0 release.&amp;#160;&amp;#160; If I nuked your favorite feature, please let me know.&amp;#160; If there’s something the Composable Context system won’t let you do, describe it, and I’ll see if it can be added.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Try-catch-fail/~4/hlKYQcghlG4" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Try-catch-fail/~3/hlKYQcghlG4/post.aspx</link>
      <author>Matt</author>
      <comments>http://trycatchfail.com/blog/post/SpecsFor-30-Preview-Available-on-NuGet.aspx#comment</comments>
      <guid isPermaLink="false">http://trycatchfail.com/blog/post.aspx?id=20942a25-9ff4-4201-8890-f097251d7cbb</guid>
      <pubDate>Mon, 07 Jan 2013 17:07:51 -1300</pubDate>
      <category>SpecsFor</category>
      <category>Testing</category>
      <dc:publisher>Matt</dc:publisher>
      <pingback:server>http://trycatchfail.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://trycatchfail.com/blog/post.aspx?id=20942a25-9ff4-4201-8890-f097251d7cbb</pingback:target>
      <slash:comments>3</slash:comments>
      <trackback:ping>http://trycatchfail.com/blog/trackback.axd?id=20942a25-9ff4-4201-8890-f097251d7cbb</trackback:ping>
      <wfw:comment>http://trycatchfail.com/blog/post/SpecsFor-30-Preview-Available-on-NuGet.aspx#comment</wfw:comment>
      <wfw:commentRss>http://trycatchfail.com/blog/syndication.axd?post=20942a25-9ff4-4201-8890-f097251d7cbb</wfw:commentRss>
    <feedburner:origLink>http://trycatchfail.com/blog/post.aspx?id=20942a25-9ff4-4201-8890-f097251d7cbb</feedburner:origLink></item>
    <item>
      <title>Using Git for Peer Reviews</title>
      <description>&lt;p&gt;This post is really more of a reference for me than anything else.&amp;#160; If you’re using Git (and you should be), and you are doing &lt;a href="http://trycatchfail.com/blog/post/Peer-Reviews.aspx"&gt;code/peer reviews&lt;/a&gt; (you are, right?), there are a few simple commands that can simplify reviewing a feature that’s spread across multiple commits.&amp;#160; Here are those commands.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;First you’ll want to see which files were changed as part of the commit.&amp;#160; Here’s a simple Powershell command that will do the trick:&lt;/p&gt;  &lt;pre class="brush: ps;"&gt;git log --grep=&amp;lt;story id&amp;gt; --name-only --pretty=format:'' | 
Get-Unique | 
sort&lt;/pre&gt;

&lt;p&gt;This grabs all the files that are changed in commits associated to a particular story ID, then pipes them to Powershell to get a list of unique names.&lt;/p&gt;

&lt;p&gt;Next, you’ll want to diff the changes to the files.&amp;#160; Find the first commit that’s part of the story, grab it’s parent commit hash (the hash of the previous commit), then grab the hash of the final commit.&amp;#160; Run this command for each file that you got from the first step:&lt;/p&gt;

&lt;pre class="brush: ps;"&gt;git difftool &amp;lt;starting hash&amp;gt; &amp;lt;ending hash&amp;gt; &amp;lt;full/path/to/file.ext&amp;gt;&lt;/pre&gt;

&lt;p&gt;This will fire up your configured diff tool with the changes between the two commits.&amp;#160; One thing to note: if there were commits in between that altered the files, you’ll also see those changes.&lt;/p&gt;

&lt;p&gt;Happy peer reviewing!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Try-catch-fail/~4/tjOXtSaso4E" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Try-catch-fail/~3/tjOXtSaso4E/post.aspx</link>
      <author>Matt</author>
      <comments>http://trycatchfail.com/blog/post/Using-Git-for-Peer-Reviews.aspx#comment</comments>
      <guid isPermaLink="false">http://trycatchfail.com/blog/post.aspx?id=1abfa55d-96f6-4273-a134-7dfdce607c2d</guid>
      <pubDate>Tue, 11 Dec 2012 14:14:29 -1300</pubDate>
      <category>git</category>
      <category>Best Practices</category>
      <dc:publisher>Matt</dc:publisher>
      <pingback:server>http://trycatchfail.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://trycatchfail.com/blog/post.aspx?id=1abfa55d-96f6-4273-a134-7dfdce607c2d</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://trycatchfail.com/blog/trackback.axd?id=1abfa55d-96f6-4273-a134-7dfdce607c2d</trackback:ping>
      <wfw:comment>http://trycatchfail.com/blog/post/Using-Git-for-Peer-Reviews.aspx#comment</wfw:comment>
      <wfw:commentRss>http://trycatchfail.com/blog/syndication.axd?post=1abfa55d-96f6-4273-a134-7dfdce607c2d</wfw:commentRss>
    <feedburner:origLink>http://trycatchfail.com/blog/post.aspx?id=1abfa55d-96f6-4273-a134-7dfdce607c2d</feedburner:origLink></item>
    <item>
      <title>SpecsFor.Mvc 2.0 Released</title>
      <description>&lt;p&gt;&lt;a href="http://specsfor.com/SpecsForMvc/" target="_blank"&gt;SpecsFor.Mvc&lt;/a&gt; 2.0 is out today.&amp;#160; This release includes drastically improved performance, support for Chrome, and support for the very latest versions of &lt;a href="http://seleniumhq.org/" target="_blank"&gt;Selenium&lt;/a&gt;, ASP.NET MVC, and other libraries. &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;This is &lt;strong&gt;not&lt;/strong&gt; what I had originally planned for the &lt;a href="http://specsfor.com/" target="_blank"&gt;SpecsFor&lt;/a&gt;.Mvc 2.0 release.&amp;#160; I had originally planned to have more performance improvements as well as a flexible system for specify conventions.&amp;#160; Unfortunately several things have forced me to make breaking changes sooner rather than later.&amp;#160; First was the release of ASP.NET MVC 4.0.&amp;#160; There were a few changes there that were causing assembly version conflicts for new projects that tried to install the SpecsFor.Mvc package.&amp;#160; Second and more importantly though are the changes that have recently been made to Selenium WebDriver.&amp;#160; &lt;/p&gt;  &lt;p&gt;Selenium is moving towards a model where the core of WebDriver no longer includes the actual web drivers.&amp;#160; Instead, they’re counting on browser vendors to supply their own web drivers.&amp;#160; This means that, out of the box, SpecsFor.Mvc 1.4 no longer included everything you needed to write awesome end-to-end tests.&amp;#160; Because installing SpecsFor.Mvc fresh grabs the latest version of Selenium WebDriver, new projects don’t have the necessary web driver servers to actually &lt;em&gt;execute&lt;/em&gt; the tests.&amp;#160; You had to go out and download the web driver server for Internet Explorer separately. &lt;/p&gt;  &lt;p&gt;I thought long and hard about how to handle this.&amp;#160; I don’t like the idea of bundling anything directly within the SpecsFor.Mvc package except for the core components of SpecsFor.Mvc itself.&amp;#160; However, the goal of the project is to make it super-easy to start writing end-to-end tests, and having people manually go and install the web driver servers just doesn’t fit that goal.&amp;#160; So, SpecsFor.Mvc 2.0 comes with two web driver server executables in the package: one for Internet Explorer (32-bit) and one for Google Chrome (yes, Chrome is now supported).&amp;#160; Firefox is still baked in to Selenium Web Driver directly for the time being.&amp;#160; That means you can use any of the three major browsers for your tests.&lt;/p&gt;  &lt;p&gt;I also made some potentially breaking changes concerning how the web drivers are used.&amp;#160; Because the web drivers are now separate executables, it is &lt;em&gt;substantially &lt;/em&gt;more expensive to create/recreate one.&amp;#160; SpecsFor.Mvc 1.4 destroyed and recreated the driver between every test, but that approach just doesn’t work with the new Selenium WebDriver model.&amp;#160; SpecsFor.Mvc 2.0 therefore reuses the same browser window for all tests.&amp;#160; This &lt;em&gt;may&lt;/em&gt; lead to some unforeseen issues.&amp;#160; Testing locally with some of my projects didn’t uncover anything, but still, this was a big enough change that it warranted the bump to “2.0” in my mind.&amp;#160; One nice thing about this change is that has a tremendous impact on speed.&amp;#160; It used to take 3-4 minutes to run approximately 100 end-to-end tests for one of my mobile apps.&amp;#160; With SpecsFor.Mvc 2.0 and Chrome, that same suite of tests completes in approximately 90 seconds. &lt;/p&gt;  &lt;p&gt;I may move the web drivers out of SpecsFor.Mvc in the next version.&amp;#160; I’m strongly considering putting them in their own NuGet packages that can be pulled in separately.&amp;#160; This will make it possible to version the various pieces separately, which will cut down on the size of the NuGet package. &lt;/p&gt;  &lt;p&gt;The SpecsFor package also received a minor upgrade to 2.7 tonight.&amp;#160; This upgrade does not include any new features, but it was rebuilt against the latest versions of its various dependencies, which should make it easier to pick up and use on new projects.&lt;/p&gt;  &lt;p&gt;If you encounter issues with either upgrade, please let me know!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Try-catch-fail/~4/2m2VWapy1ho" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Try-catch-fail/~3/2m2VWapy1ho/post.aspx</link>
      <author>Matt</author>
      <comments>http://trycatchfail.com/blog/post/SpecsForMvc-20-Released.aspx#comment</comments>
      <guid isPermaLink="false">http://trycatchfail.com/blog/post.aspx?id=49b69c88-5c51-4de9-ac8d-c799490c6d39</guid>
      <pubDate>Sat, 15 Sep 2012 14:41:07 -1300</pubDate>
      <category>SpecsFor</category>
      <category>MVC</category>
      <dc:publisher>Matt</dc:publisher>
      <pingback:server>http://trycatchfail.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://trycatchfail.com/blog/post.aspx?id=49b69c88-5c51-4de9-ac8d-c799490c6d39</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://trycatchfail.com/blog/trackback.axd?id=49b69c88-5c51-4de9-ac8d-c799490c6d39</trackback:ping>
      <wfw:comment>http://trycatchfail.com/blog/post/SpecsForMvc-20-Released.aspx#comment</wfw:comment>
      <wfw:commentRss>http://trycatchfail.com/blog/syndication.axd?post=49b69c88-5c51-4de9-ac8d-c799490c6d39</wfw:commentRss>
    <feedburner:origLink>http://trycatchfail.com/blog/post.aspx?id=49b69c88-5c51-4de9-ac8d-c799490c6d39</feedburner:origLink></item>
    <item>
      <title>The Decorator Pattern, Done Right, With StructureMap</title>
      <description>&lt;p&gt;One of the cool bits of black magic I showed during my “StructureMapping Your Way to Better Software” talk was an extension method for registering decorators using &lt;a href="http://structuremap.net/structuremap/" target="_blank"&gt;StructureMap&lt;/a&gt;.&amp;#160; In this post, I’ll show you how it works. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://trycatchfail.com/blog/image.axd?picture=image_65.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://trycatchfail.com/blog/image.axd?picture=image_thumb_65.png" width="404" height="306" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h2&gt;EnrichWith Says What? &lt;/h2&gt;  &lt;p&gt;StructureMap actually supports the &lt;a href="http://c2.com/cgi/wiki?DecoratorPattern" target="_blank"&gt;decorator pattern&lt;/a&gt; right out of the box.&amp;#160; This functionality is cleverly concealed in plain sight in the EnrichWith method:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;var container = new Container(cfg =&amp;gt;
    {
        //...
        
        cfg.For&amp;lt;IProductRepository&amp;gt;()
            .Use&amp;lt;InMemoryProductRepository&amp;gt;()
            .EnrichWith((ctx, r) =&amp;gt;
                {
                    return new ProductRepoLogger(r, ctx.GetInstance&amp;lt;User&amp;gt;());
                });

        //...
    });

var repo = container.GetInstance&amp;lt;IProductRepository&amp;gt;();
//Repo is actually a ProductRepoLogger that wraps an InMemoryProductRepository.&lt;/pre&gt;

&lt;p&gt;There are several problems with this method though.&amp;#160; First, it doesn’t read very well.&amp;#160; At all.&amp;#160; Especially when you want to apply multiple decorators:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;var container = new Container(cfg =&amp;gt;
    {
        //...
        
        cfg.For&amp;lt;IProductRepository&amp;gt;()
            .Use&amp;lt;InMemoryProductRepository&amp;gt;()
            .EnrichWith((ctx, r) =&amp;gt;
                {
                    return new ProductRepoLogger(
                        new ProductSecurityDecorator(r, ctx.GetInstance&amp;lt;IProductAuthorizer&amp;gt;(), ctx.GetInstance&amp;lt;User&amp;gt;()), 
                        ctx.GetInstance&amp;lt;User&amp;gt;());
                });

        //...
    });

var repo = container.GetInstance&amp;lt;IProductRepository&amp;gt;();
//Repo is now ProductRepoLogger that wraps a ProductSecurityDecorator that wraps an InMemoryProductRepository.&lt;/pre&gt;

&lt;p&gt;Imagine if you added a third (or fourth) decorator, or if your decorators had more dependencies than the simple example above. &lt;/p&gt;

&lt;p&gt;The other, bigger problem is that it tightly-couples your configuration code to implementation details of your decorators.&amp;#160; What happens if you want need to add an additional dependency to your decorator?&amp;#160; You’ll need to go back and update anywhere that you’ve applied that decorator.&amp;#160; That really defeats some of the advantages of using an IoC container in the first place.&amp;#160; &lt;/p&gt;

&lt;h2&gt;A Better Way&lt;/h2&gt;

&lt;p&gt;If the above code doesn’t strike you as something you want to have to look at ever again, I made an extension method for you:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;var container = new Container(cfg =&amp;gt;
    {
        //...
        
        cfg.For&amp;lt;IProductRepository&amp;gt;().Use&amp;lt;InMemoryProductRepository&amp;gt;()
            .Decorate().With&amp;lt;ProductSecurityDecorator&amp;gt;()
            .AndThen&amp;lt;ProductRepoLogger&amp;gt;()
            .AndThen&amp;lt;RudeProductRepoLogger&amp;gt;();
        cfg.For&amp;lt;IProductAuthorizer&amp;gt;().Use&amp;lt;ProductAuthorizer&amp;gt;();
        
        //...
    });

var repo = container.GetInstance&amp;lt;IProductRepository&amp;gt;();&lt;/pre&gt;

&lt;p&gt;The above allows you to chain multiple decorators together &lt;em&gt;cleanly&lt;/em&gt;.&amp;#160; No more nesting up ‘new’ statements, no more using the context to manually locate dependencies.&amp;#160; The decorators are created through the container, so they can take full advantage of dependency injection.&amp;#160; That means no more tight coupling between your config code and your decorator constructors!&lt;/p&gt;

&lt;h2&gt;How Does it Work?&lt;/h2&gt;

&lt;p&gt;I’m a bit embarrassed to say that it actually took me three attempts to implement this alternative.&amp;#160; I tried and failed twice before because I overlooked a simple, obvious approach: register the “inner” instance using IContext.RegisterDefault!&amp;#160;&amp;#160; The extension method returns a DecoratedInstance that can be used to recursively build up decorator definitions:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class DecoratedInstance&amp;lt;TTarget&amp;gt;
{
    //...
    
    public DecoratedInstance&amp;lt;TTarget&amp;gt; AndThen&amp;lt;TDecorator&amp;gt;()
    {
        //Must be captured as a local variable, otherwise the closure's decorator will
        //always be the outer-most decorator, causing a Stack Overflow.
        var previousDecorator = _decorator;

        ContextEnrichmentHandler&amp;lt;TTarget&amp;gt; newDecorator = (ctx, t) =&amp;gt;
            {
                var pluginType = ctx.BuildStack.Current.RequestedType;

                var innerInstance = previousDecorator(ctx, t);

                ctx.RegisterDefault(pluginType, innerInstance);

                return ctx.GetInstance&amp;lt;TDecorator&amp;gt;();
            };

        _instance.EnrichWith(newDecorator);

        _decorator = newDecorator;

        return this;
    }
}&lt;/pre&gt;

&lt;h2&gt;What’s It Good For? &lt;/h2&gt;

&lt;p&gt;The decorator pattern is one of my favorite design patterns.&amp;#160; It’s an awesome way to encapsulate behaviors and responsibilities into composable pieces.&amp;#160; Here are a few examples using a a simple repository:&lt;/p&gt;

&lt;h3&gt;Logging&lt;/h3&gt;

&lt;pre class="brush: csharp;"&gt;public class ProductRepoLogger : IProductRepository
{
    private readonly IProductRepository _target;
    private readonly User _user;

    public ProductRepoLogger(IProductRepository target, User user)
    {
        _target = target;
        _user = user;
    }

    public Product Find(int id)
    {
        Console.WriteLine(&amp;quot;{0} is requesting product {1}.&amp;quot;, _user, id);

        return _target.Find(id);
    }
}&lt;/pre&gt;

&lt;h3&gt;Security&lt;/h3&gt;

&lt;pre class="brush: csharp;"&gt;public class ProductSecurityDecorator : IProductRepository
{
    private readonly IProductRepository _target;
    private readonly IProductAuthorizer _securityService;
    private readonly User _currentUser;

    public ProductSecurityDecorator(IProductRepository target, IProductAuthorizer securityService, User currentUser)
    {
        _target = target;
        _securityService = securityService;
        _currentUser = currentUser;
    }

    public Product Find(int id)
    {
        if (_securityService.IsUserAuthorizedToAccessProduct(_currentUser, id))
        {
            return _target.Find(id);
        }
        else
        {
            throw new SecurityException(&amp;quot;You are not authorized to access this product!&amp;quot;);
        } 
    }
}&lt;/pre&gt;

&lt;h3&gt;Caching&lt;/h3&gt;

&lt;pre class="brush: csharp;"&gt;public class ProductCachingDecorator : IProductRepository
{
    private readonly IProductRepository _innerRepo;
    private readonly ConcurrentDictionary&amp;lt;int, Product&amp;gt; _cache;

    public ProductCachingDecorator(IProductRepository innerRepo)
    {
        _innerRepo = innerRepo;
        _cache = new ConcurrentDictionary&amp;lt;int, Product&amp;gt;();
    }

    public Product Find(int id)
    {
        return _cache.GetOrAdd(id, _ =&amp;gt; _innerRepo.Find(id));
    }
}&lt;/pre&gt;

&lt;p&gt;By breaking behaviors apart, the original repository remains simple and clean, and the behaviors can be reused with any repository that implements the interface.&amp;#160; &lt;/p&gt;

&lt;h2&gt;Where Can I Get It? &lt;/h2&gt;

&lt;p&gt;I don’t have a good project for this (yet), so I’ve created a &lt;a href="https://gist.github.com/3687346" target="_blank"&gt;Gist with the required pieces&lt;/a&gt;.&amp;#160; If anyone has any suggestions on where to put this functionality, let me know.&amp;#160; If you want to see a full example, check out my &lt;a href="https://github.com/MattHoneycutt/Presentations/tree/master/StructureMappingYourWayToBetterSoftware/TryCatchFail.LearnStructureMap" target="_blank"&gt;“Learning Structure” map sample project&lt;/a&gt;.&amp;#160; Questions or comments?&amp;#160; Leave ‘em below!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Try-catch-fail/~4/Q5CQbGg8Eoo" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Try-catch-fail/~3/Q5CQbGg8Eoo/post.aspx</link>
      <author>Matt</author>
      <comments>http://trycatchfail.com/blog/post/The-Decorator-Pattern-Done-Right-With-StructureMap.aspx#comment</comments>
      <guid isPermaLink="false">http://trycatchfail.com/blog/post.aspx?id=a60e0740-2efd-4cd3-bec7-7b303624541c</guid>
      <pubDate>Sun, 09 Sep 2012 08:16:33 -1300</pubDate>
      <category>IoC</category>
      <category>StructureMap</category>
      <category>DesignPatterns</category>
      <dc:publisher>Matt</dc:publisher>
      <pingback:server>http://trycatchfail.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://trycatchfail.com/blog/post.aspx?id=a60e0740-2efd-4cd3-bec7-7b303624541c</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://trycatchfail.com/blog/trackback.axd?id=a60e0740-2efd-4cd3-bec7-7b303624541c</trackback:ping>
      <wfw:comment>http://trycatchfail.com/blog/post/The-Decorator-Pattern-Done-Right-With-StructureMap.aspx#comment</wfw:comment>
      <wfw:commentRss>http://trycatchfail.com/blog/syndication.axd?post=a60e0740-2efd-4cd3-bec7-7b303624541c</wfw:commentRss>
    <feedburner:origLink>http://trycatchfail.com/blog/post.aspx?id=a60e0740-2efd-4cd3-bec7-7b303624541c</feedburner:origLink></item>
    <item>
      <title>devLink 2012 Wrap-up</title>
      <description>&lt;p&gt;Well, devLink 2012 is over.&amp;#160; I got exactly what I expected out of the event: a great time, some new ideas, some great interactions, and some great experience.&amp;#160; I see now that I was only partially abusing the Pomodoro technique thanks to @joelcochran, I learned &lt;em&gt;a lot&lt;/em&gt; about JavaScript from @ifandelse, and I learned that LINQ really has nothing to do with IEnumerable thanks to an awesome presentation by @kodefuguru.&amp;#160; &lt;/p&gt;  &lt;p&gt;I had a great time talking about &lt;a href="http://specsfor.com/" target="_blank"&gt;SpecsFor&lt;/a&gt; and about StructureMap.&amp;#160; My SpecsFor talk was much rougher than any of the other times I’ve presented it, but I’d like to think that I redeemed myself with my StructureMap talk.&amp;#160; Thanks, everyone, who provided feedback.&amp;#160; It really does help, and it will help me be that much better next time.&amp;#160; &lt;/p&gt;  &lt;p&gt;Anyway, My code and slides are now online for anyone that is interested (links below).&amp;#160; I’ll be posting more details, particularly about some of the &lt;a href="http://structuremap.net/structuremap/" target="_blank"&gt;StructureMap&lt;/a&gt; black magic that I showed, over the coming days (weeks/months).&amp;#160; I’m also putting together a refreshed build of &lt;a href="http://specsfor.com/" target="_blank"&gt;SpecsFor.Mvc&lt;/a&gt; to address the compatibility problems introduced by .NET 4.5 final, &lt;em&gt;and&lt;/em&gt; I’m going to be working on getting some other things posted that I’ve been dragging my feet on.&amp;#160; It’s going to be a busy few weeks around here…&lt;/p&gt;  &lt;p&gt;StructureMapping Your Way to Better Software – &lt;a href="http://www.slideshare.net/matthoneycutt/structure-mapping-your-way-to-better-software" target="_blank"&gt;Slides&lt;/a&gt;, &lt;a href="https://github.com/MattHoneycutt/Presentations/tree/master/StructureMappingYourWayToBetterSoftware" target="_blank"&gt;Code&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Integration Testing with SpecsFor.Mvc – &lt;a href="http://www.slideshare.net/matthoneycutt/integration-testing-with-specs-formvc" target="_blank"&gt;Slides&lt;/a&gt;, &lt;a href="https://github.com/MattHoneycutt/Fail-Tracker" target="_blank"&gt;Code&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Try-catch-fail/~4/4sHC6Gw6EqA" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Try-catch-fail/~3/4sHC6Gw6EqA/post.aspx</link>
      <author>Matt</author>
      <comments>http://trycatchfail.com/blog/post/devLink-2012-Wrap-up.aspx#comment</comments>
      <guid isPermaLink="false">http://trycatchfail.com/blog/post.aspx?id=c6d1c58d-ab3a-4cdb-8746-7063f87b00a6</guid>
      <pubDate>Mon, 03 Sep 2012 08:30:52 -1300</pubDate>
      <category>Misc</category>
      <dc:publisher>Matt</dc:publisher>
      <pingback:server>http://trycatchfail.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://trycatchfail.com/blog/post.aspx?id=c6d1c58d-ab3a-4cdb-8746-7063f87b00a6</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://trycatchfail.com/blog/trackback.axd?id=c6d1c58d-ab3a-4cdb-8746-7063f87b00a6</trackback:ping>
      <wfw:comment>http://trycatchfail.com/blog/post/devLink-2012-Wrap-up.aspx#comment</wfw:comment>
      <wfw:commentRss>http://trycatchfail.com/blog/syndication.axd?post=c6d1c58d-ab3a-4cdb-8746-7063f87b00a6</wfw:commentRss>
    <feedburner:origLink>http://trycatchfail.com/blog/post.aspx?id=c6d1c58d-ab3a-4cdb-8746-7063f87b00a6</feedburner:origLink></item>
  </channel>
</rss>
