<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9200551703084243537</id><updated>2026-10-14T05:27:49.581-05:00</updated><category term="C#"/><category term="testing"/><category term="ASP.NET MVC"/><category term="Dapper"/><category term=".NET"/><category term="Attribute"/><category term="DataTables"/><category term="Entity Framework"/><category term="TDD"/><category term="WebAPI"/><category term="extensions"/><category term="jQuery UI"/><category term=".NET Core"/><category term="Action"/><category term="Analytics"/><category term="AutoMapper"/><category term="Autofac"/><category term="Azure"/><category term="Azure App Service"/><category term="EF5"/><category term="Factory Pattern"/><category term="FakeItEasy"/><category term="Git"/><category term="HTTP Headers"/><category term="IEnumerable"/><category term="Integrity"/><category term="JavaScript"/><category term="JsonResult"/><category term="LINQ LINQtoSQL DataContext .NET mocking"/><category term="LINQtoSQL"/><category term="Learning"/><category term="MSBuild"/><category term="MiniProfiler"/><category term="Passion"/><category term="RequireJS"/><category term="Security"/><category term="WebJob"/><category term="anonymous type"/><category term="data modeling"/><category term="expression"/><category term="iframe"/><category term="jQuery Cycle slideshow mvc asp.net"/><category term="jQuery mvc session logout"/><category term="linq"/><category term="linq linqtosql audit"/><category term="messaging"/><category term="mocking"/><category term="nerd geek"/><title type='text'>Farm Fresh Code</title><subtitle type='html'>Greetings from the Heartland.  Quality code, delivered fresh to you.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>46</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-395312971206974729</id><published>2019-03-16T10:15:00.000-05:00</published><updated>2019-03-16T10:23:11.115-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET Core"/><category scheme="http://www.blogger.com/atom/ns#" term="Azure App Service"/><category scheme="http://www.blogger.com/atom/ns#" term="HTTP Headers"/><category scheme="http://www.blogger.com/atom/ns#" term="Security"/><title type='text'>Remove Server Headers in Azure App Service for ASP.NET Core</title><content type='html'>I&#39;m late to the game, mostly because I haven&#39;t been working on web apps for quite some time, but I recently wanted to do some basic security functions on a .NET Core 2.2 application being deployed to an Azure App Service, namely removing headers that identify the platform being used. I have a pretty standard way that I&#39;d done this previously for ASP.NET MVC, but those methods don&#39;t work in .NET Core. After doing some digging around, I found that I needed to add a skeleton web.config to configure the web server in the Azure app.&lt;br /&gt;
&lt;br /&gt;
In the configuration included below, you&#39;ll see that I&#39;m using the &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;HttpProtocol&lt;/span&gt; element to remove the &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;X-Powered-By&lt;/span&gt; header. To remove the &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Server&lt;/span&gt; header, I&#39;m using the request filtering feature of IIS 10.0 that has been added to the Azure App Service web server.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background: #f0f0f0; border: 1px dashed #cccccc; color: black; font-family: &amp;quot;arial&amp;quot;; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt; &amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;  
 &amp;lt;configuration&amp;gt;  
  &amp;lt;system.webServer&amp;gt;  
   &amp;lt;handlers&amp;gt;  
    &amp;lt;remove name=&quot;aspNetCore&quot; /&amp;gt;  
    &amp;lt;add name=&quot;aspNetCore&quot;   
       path=&quot;*&quot;   
       verb=&quot;*&quot;   
       modules=&quot;AspNetCoreModuleV2&quot;   
       resourceType=&quot;Unspecified&quot; /&amp;gt;  
   &amp;lt;/handlers&amp;gt;  
   &amp;lt;aspNetCore processPath=&quot;%LAUNCHER_PATH%&quot;   
         arguments=&quot;%LAUNCHER_ARGS%&quot;   
         stdoutLogEnabled=&quot;false&quot;   
         stdoutLogFile=&quot;.\logs\stdout&quot;   
         hostingModel=&quot;InProcess&quot;&amp;gt;  
   &amp;lt;/aspNetCore&amp;gt;  
   &amp;lt;httpProtocol&amp;gt;  
    &amp;lt;customHeaders&amp;gt;  
     &amp;lt;remove name=&quot;X-Powered-By&quot; /&amp;gt;  
    &amp;lt;/customHeaders&amp;gt;  
   &amp;lt;/httpProtocol&amp;gt;  
   &amp;lt;security&amp;gt;  
    &amp;lt;requestFiltering removeServerHeader=&quot;true&quot; /&amp;gt;  
   &amp;lt;/security&amp;gt;  
  &amp;lt;/system.webServer&amp;gt;  
 &amp;lt;/configuration&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
NOTE: I&#39;m not using Kestrel for this service; it&#39;s being hosted by IIS.  If you are using Kestrel, you can use middleware to remove the &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Server&lt;/span&gt; header.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background: #f0f0f0; border: 1px dashed #cccccc; color: black; font-family: &amp;quot;arial&amp;quot;; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt;  public static IWebHostBuilder CreateWebHostBuilder(string[] args) =&amp;gt;  
    WebHost.CreateDefaultBuilder(args)  
           .UseKestrel(o =&amp;gt; o.AddServerHeader = false)  
           .UseStartup&amp;lt;Startup&amp;gt;();  
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/395312971206974729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2019/03/remove-server-headers-in-azure-app.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/395312971206974729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/395312971206974729'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2019/03/remove-server-headers-in-azure-app.html' title='Remove Server Headers in Azure App Service for ASP.NET Core'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-6161691115654892513</id><published>2018-12-04T16:51:00.001-06:00</published><updated>2018-12-04T16:51:39.037-06:00</updated><title type='text'>Controller Testing</title><content type='html'>Prompted by a &lt;a href=&quot;https://twitter.com/amandaiverso/status/1070039097077465088&quot; rel=&quot;nofollow&quot;&gt;tweet &lt;/a&gt;from&amp;nbsp;&lt;a href=&quot;https://twitter.com/amandaiverso&quot; rel=&quot;nofollow&quot;&gt;@amandaiverso &lt;/a&gt;(retweeted by Scott Hanselman), I&#39;ve decided to write down a few thoughts on what I consider to be &quot;industry standard&quot; (or at least my standard) for testing controllers. First, I should say that most often these days I&#39;m writing APIs not web sites. That will likely skew my thoughts, but I&#39;ll try to be more general or at least differentiate where necessary between the two because there are subtle differences. My thoughts are going to cover both how and what to test. The what probably goes at least somewhat to what I think controllers ought to do, not just what you ought to test. I haven&#39;t spent a lot of time thinking this through - it&#39;s mostly a quick response to the tweet. I&#39;d be happy to get additional thoughts about this from others.&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;h2&gt;Kinds of Tests&lt;/h2&gt;&lt;div&gt;For controllers I typically do 2 or 3 types of testing. The two types of tests that I would always create are integration tests and unit tests. In some, but not all scenarios, I might add a quasi-integration test. What do I mean by that? In my practice it would be an automated test using a unit-test framework but invoking an in-memory server implementation. This type of test allows me to test the plumbing set up around the controller to ensure things like any custom model-binding or authentication is properly configured. In this latter case, because I typically mock out everything but the controller, I would consider it mostly a controller integration test, but I&#39;d typically have them executed with the unit tests because they can be done fast enough to be run as unit tests and in isolation from other parts of the environment so that they can easily be run by the build server.&amp;nbsp; For API tests, I would probably also write unit tests using reflection to validate key parts of my attribute-based Swashbuckle documentation - ensuring for example that the return values of any actions match that documented via the attribute and that all public actions have certain types of document attributes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;h2&gt;Approach to Testing&lt;/h2&gt;&lt;div&gt;Generally I follow an approach that keeps controller actions thin. Normally this means that my controllers handle some (but not all) validation, authorization, and output formatting.&amp;nbsp; They delegate business logic and data access to services. The things that I would test then are both success and failure conditions for the validation that is handled at the controller level, valid and invalid access, and proper translation of service models into view-specific models either for use in an MVC view or for presentation on the wire in an API. In the latter case, I&#39;m mostly checking that the model is populated correctly. I don&#39;t typically mock out my mapping services, usually AutoMapper, so this functions as a check that they are configured properly when used.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;h3&gt;Validation&lt;/h3&gt;&lt;div&gt;Much of the time I used model-based validation. Typically I&#39;ll ensure that my controller checks Model.IsValid. If I&#39;m using Fluent validation, then I&#39;ll make sure that it invokes the validator and properly responds depending on the validator&#39;s response. For Model.IsValid checking, this is typically configured in the test set up by constructing a controller context and setting the ModelState.IsValid property directly. In my controller tests for this I&#39;m not particularly interested in whether the model binder works correctly (&quot;don&#39;t test the framework&quot;), just that my code responds correctly when it is either valid or invalid.&amp;nbsp; I&#39;ll test this by checking the output of the action being tested.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;For manually invoked validation, I&#39;ll use mocks with particular set ups, then verify that the validator is called, then test the output of the action to ensure that the controller properly responded to the validation result the mock returns.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;h3&gt;Access&lt;/h3&gt;&lt;div&gt;Since access is frequently enforced by attributes, this is a place where I might use quasi-integration tests. If an API is public or all access is controlled by restricting IP ranges, then I might skip these. If I am testing these, then the tests use the set up to establish responses from authentication and authorization services, create a request using the credentials that trigger the configured responses, then checking that the proper response code is return in failure cases or that a valid OK response is returned in success cases. These tests typically don&#39;t inspect the response values, just the error codes. Some configuration for other services is required to ensure that you don&#39;t get errors from invalid data, but these can be configured loosely to avoid tight coupling to their implementations. Using something like AutoFixture works well to ensure that I get valid data without too much configuration trouble.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;h3&gt;Model Translation&lt;/h3&gt;&lt;div&gt;I typically treat model translation as whitebox testing. If I&#39;m using something like AutoMapper, then I&#39;m probably not rigorous in testing every individual property is being set. Those things that are a straightforward translation from the entity model to the view model don&#39;t really need to be tested. You can verify that they are handled by validating the AutoMapper configuration - that will let you know where you might have missing properties.&amp;nbsp; Generally, I&#39;ll restrict myself to making sure an important property has been copied correctly (the Id property is a good choice if it&#39;s a primary key) and then any custom mappings/flattenings that I expect to occur for that particular model.&amp;nbsp; Again, I don&#39;t try to test the framework, in this case AutoMapper, but only those things that I&#39;ve customized. When testing one property, say of a flattened model, will suffice to ensure that the entire model has been flattened, I&#39;ll do that. Where it&#39;s possible to make mistakes, I&#39;ll be more rigorous.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/6161691115654892513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2018/12/controller-testing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/6161691115654892513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/6161691115654892513'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2018/12/controller-testing.html' title='Controller Testing'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-6419209986721287804</id><published>2017-11-03T09:20:00.000-05:00</published><updated>2017-11-03T09:20:04.000-05:00</updated><title type='text'>Sustainability: Refactoring, Design, and Testing</title><content type='html'>I recently saw a Twitter &lt;a href=&quot;https://twitter.com/ploeh/status/926438776192237570&quot; rel=&quot;nofollow&quot;&gt;post by Mark Seemann&lt;/a&gt; preferring the term &quot;sustainable code&quot; over &quot;maintainable code.&quot; As it happens I had also been having some conversations about TDD (Test Driven Design) at work. Most people, when they think of unit testing, think the purpose is to reduce code errors. To be sure, that is an important aspect of unit testing and writing tests first, I think, has led to me making fewer errors and introducing fewer bugs than I would otherwise. I find this out every time I prototype something without tests then convert it into production code by introducing tests after the fact. (Yes, I&#39;m not a TDD purist) Invariably as I start writing tests I find cases that I hadn&#39;t thought about and even - gasp - errors that I didn&#39;t even recognize but that were obvious after having written a test.&lt;br /&gt;
&lt;br /&gt;
The concept of &quot;sustainable code&quot; is really why I&#39;ve settled on TDD as a core practice. I should say TDD and refactoring because I believe the two go hand in hand - at least for me, and if my experience with other developers I work with over time is an indication of general trends, likely you as well.&lt;br /&gt;
&lt;br /&gt;
In my experience, if you don&#39;t write tests first, you don&#39;t write tests - or at least many tests, the number of tests that it would take to allow you to refactor safely and confidently. In my internal conversations I talked about &quot;refactoring with abandon&quot; but it&#39;s not as undirected as that implies, but certainly you will have a lot less fear of breaking things and will engage in refactorings that would otherwise seem foolish indeed. I have both written test-first and test-last. Writing tests last feels like an onerous chore that you have to force yourself to do. It&#39;s easy to write just the happy path tests - and since you&#39;ve already written the code, you know how to write a test that makes that code pass.&amp;nbsp; When I write tests first, it&#39;s part of design. I&#39;m thinking, not of how to write a passing test, but how to make the code do all the things I think it should do. It&#39;s a creative activity not a bookkeeping activity. It makes a HUGE difference in the joy I get from writing that code.&lt;br /&gt;
&lt;br /&gt;
Refactoring, continually improving code as you&#39;re creating new features, is the key to sustainable code. I&#39;ll note here that &quot;refactoring&quot; is not &quot;changing what the code does&quot; but rather &quot;how the code does it.&quot;&amp;nbsp; In other words, if you&#39;ve written tests, then those tests shouldn&#39;t need to change as a result of a refactoring. If they do, then you&#39;ve over-specified in your tests. That sometimes happens, but usually you can easily tell whether a refactoring has broken behavior or broken a specification that was too prescriptive.&amp;nbsp; In that way refactoring can improve both your tests AND your code.&lt;br /&gt;
&lt;br /&gt;
The key to being able to refactor with confidence is having a set of tests that will tell you when what you have changed breaks something in an unintended way.&amp;nbsp; If I make a change and a test starts failing, and that failure isn&#39;t merely an over-specification, then that change isn&#39;t an improvement, it&#39;s a bug.&amp;nbsp; I need to go back and continue making the improvement to account for the behavior I&#39;ve broken.&amp;nbsp; This is especially true once the code has gotten complicated enough that you can no longer keep an accurate model of how things work in your head. At that point you begin to rely more heavily on your tests as a safety net; they&#39;re the embodiment of the working knowledge you had about that part of the code at the time that you most understood it.&lt;br /&gt;
&lt;br /&gt;
Once you&#39;re able to refactor with confidence, you have a platform upon which you can build a system sustainably.&amp;nbsp; When you see inevitably see a piece of code that you now know is crappy, given your increased understanding of programming or changes in technology that allow a better solution, you can change it with confidence, knowing that the code still does what it was intended to do.&amp;nbsp; When you add a new feature to something that is a dependency for something else, you can be sure that you&#39;re not breaking anything upstream that relies on it because you have tests to ensure that you&#39;re not breaking existing behavior.&lt;br /&gt;
&lt;br /&gt;
For me the big win with TDD is sustainability. You can continue to improve and extend the useful life of your software without the expense of a ground-up rewrite. There are huge cost savings over the lifetime of your software that result from using TDD and refactoring. Fewer bugs is a really, really nice side-effect, but it&#39;s not the primary reason I do TDD any more. It&#39;s about keeping the codebase clean and easy to work in, and easier to innovate on and add new features that drive revenue or customer satisfaction.</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/6419209986721287804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2017/11/sustainability-refactoring-design-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/6419209986721287804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/6419209986721287804'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2017/11/sustainability-refactoring-design-and.html' title='Sustainability: Refactoring, Design, and Testing'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-2835739695430079211</id><published>2016-08-03T23:54:00.000-05:00</published><updated>2016-08-03T23:54:08.166-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET"/><category scheme="http://www.blogger.com/atom/ns#" term="Azure"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="WebJob"/><title type='text'>Converting a Console Application to an Azure WebJob</title><content type='html'>&lt;p&gt;I recently gave a &lt;a href=&quot;https://speakerdeck.com/tvanfosson/working-with-webjobs-icc17-2016&quot;&gt;talk&lt;/a&gt; at Iowa Code Camp on Working with WebJobs.&amp;nbsp; I got a follow up request for resources on converting an existing console application to a WebJob. The process is relatively simple and involves three steps.&lt;/p&gt;&lt;h1&gt;Create an Azure WebApp to host your WebJob.&lt;/h1&gt;&lt;p&gt;Let’s say you have a solution that contains a console application such as the one shown below. We have a &lt;em&gt;Program&lt;/em&gt; class that contains the &lt;em&gt;Main&lt;/em&gt; method. This method creates the object that performs the task and its dependencies, then invokes one or more methods on the class to perform the work. You’d probably have some logging and some error handling, but we’ll omit that for the sake of clarity.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhznzjjg8Bx8uHEn0c1MhqHj4ZhSTP1JuPMnDCGvnRF-nwDuNIuCYtYBVzmzDLj7sH-RKOdPJqn7nR7WnmF_C0DrI8rub8V7Fap2YbD4WqBr4auDa0Iho46c7sCeF6ed8vsXA3Fk4IzrK8/s1600-h/Project%25255B6%25255D.png&quot;&gt;&lt;img title=&quot;Project&quot; style=&quot;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&quot; border=&quot;0&quot; alt=&quot;Project&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjh-JBDSvS0fq_zSd5T-sGTIhEahCOdIpCfme_JGwjZOnWd50IxbYZ3Nca12uR2d0-IGTlOFn_AOu5jmEX2wAEPrQrEuwnijCSeLhyNLOvNb57p3mT8C_4QHMfHQwkxqFr7INb1g4oqP_g//?imgmax=800&quot; width=&quot;583&quot; height=&quot;412&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Now, add a WebApp project to the solution.&amp;nbsp; We’ll call it WebJob.Host.&amp;nbsp; I’m creating an MVC project because I want to have a single action that can be used to display the version of the code that’s deployed as a sanity check. If you have an existing site you’re deploying as an Azure WebApp, you could use that instead.&amp;nbsp; It will need to be in the same solution as the project that we will be converting to a WebJob.&amp;nbsp; Remember to update all the packages once you’ve created the project and to clean up any boilerplate that you don’t want.&amp;nbsp; I’m going to get rid of all but the HomeController and Index action.&amp;nbsp; Don’t be surprised if VisualStudio needs to restart to complete updating your packages.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi36v5BLec2GzbZMnetKWtQU5SploE_Fk6xNX5J05gZ8XwvThVrPm327a6mmdot_iTn8_dFnOqqxmkXrvQahTo2KVAuQWe1tG3aoTnJEDgOh_3iY546P5F1HtaLD_HDUeQk_XwQXq_yJfE/s1600-h/AddWebJobProject%25255B4%25255D.png&quot;&gt;&lt;img title=&quot;AddWebJobProject&quot; style=&quot;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&quot; border=&quot;0&quot; alt=&quot;AddWebJobProject&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghiWZ6TF4M_WHHMmBnBJQe1ZNL5tzQcAvKtenWv092eb1ZwR8rbnsLQg7d0fidD6BX-sGh_xrIwgfOV-WMWCoZplpM4UdalDrBv-r4K5YQ86Eo1y3JxwR9fD5yaJGZ7SFLgxJCae5RmVM//?imgmax=800&quot; width=&quot;583&quot; height=&quot;412&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The best way to autogenerate your version information is using the capabilities of your build server. Both TeamCity and AppVeyor support this. If you’re interested in a way to update your Assembly from your repo with version information without using a CI server, I’ve written up a way to do it using &lt;a href=&quot;https://farm-fresh-code.blogspot.com/2015/03/convention-driven-automatic-release.html&quot;&gt;MSBuild Community Tasks&lt;/a&gt;.&amp;nbsp; I’m going to take the easy way out and manually keep my AssemblyInformationalVersion up-to-date for this project.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Make sure your hosting web application works before adding a WebJob to it.&lt;/strong&gt;&lt;/p&gt;&lt;h1&gt;Convert Your App to A WebJob&lt;/h1&gt;&lt;p&gt;First, we need to add the appropriate WebJob Packages. At this point I’ll assume you’re not using any Azure resource or, if you are, you can figure out the additional WebJob packages you’ll need to work with those resources. If you’re using a ServiceBus queue or topic listener, it might be easier to start from scratch and create a WebJob with an appropriate listener, then merge your existing dependencies into that rather than try to convert the older service bus client code over.&lt;/p&gt;&lt;p&gt;For a standard WebJob that is run on a schedule, you’ll need the following package:&lt;/p&gt;&lt;p&gt;Microsoft.Azure.WebJobs&lt;/p&gt;&lt;p&gt;(note: This has several dependencies, which in turn have more dependencies. Don’t be alarmed by this.)&lt;/p&gt;&lt;p&gt;Again, it’s a good practice to make sure you update your dependencies after you add them to your project to make sure you have the latest versions.&lt;/p&gt;&lt;p&gt;This is what my packages.config file looks like after installing only the WebJobs package and it’s dependencies.&lt;/p&gt;&lt;pre class=&quot;brush: xml;&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;packages&amp;gt;
  &amp;lt;package id=&quot;Microsoft.Azure.KeyVault.Core&quot; version=&quot;1.0.0&quot; targetFramework=&quot;net452&quot; /&amp;gt;
  &amp;lt;package id=&quot;Microsoft.Azure.WebJobs&quot; version=&quot;1.1.2&quot; targetFramework=&quot;net452&quot; /&amp;gt;
  &amp;lt;package id=&quot;Microsoft.Azure.WebJobs.Core&quot; version=&quot;1.1.2&quot; targetFramework=&quot;net452&quot; /&amp;gt;
  &amp;lt;package id=&quot;Microsoft.Data.Edm&quot; version=&quot;5.7.0&quot; targetFramework=&quot;net452&quot; /&amp;gt;
  &amp;lt;package id=&quot;Microsoft.Data.OData&quot; version=&quot;5.7.0&quot; targetFramework=&quot;net452&quot; /&amp;gt;
  &amp;lt;package id=&quot;Microsoft.Data.Services.Client&quot; version=&quot;5.7.0&quot; targetFramework=&quot;net452&quot; /&amp;gt;
  &amp;lt;package id=&quot;Microsoft.WindowsAzure.ConfigurationManager&quot; version=&quot;3.2.1&quot; targetFramework=&quot;net452&quot; /&amp;gt;
  &amp;lt;package id=&quot;Newtonsoft.Json&quot; version=&quot;9.0.1&quot; targetFramework=&quot;net452&quot; /&amp;gt;
  &amp;lt;package id=&quot;System.Spatial&quot; version=&quot;5.7.0&quot; targetFramework=&quot;net452&quot; /&amp;gt;
  &amp;lt;package id=&quot;WindowsAzure.Storage&quot; version=&quot;7.1.2&quot; targetFramework=&quot;net452&quot; /&amp;gt;
&amp;lt;/packages&amp;gt;
&lt;/pre&gt;&lt;p&gt;Now that we have the appropriate packages, we can convert our &lt;em&gt;Program&lt;/em&gt; to get the job set up and invoked as a WebJob. I suggest the following approach.&amp;nbsp; Create a class named &lt;em&gt;Functions&lt;/em&gt; (this is the convention) and add a method – it can be static or an instance method, whichever fits your needs best.&amp;nbsp; Migrate the code from your &lt;em&gt;Main&lt;/em&gt; method to the new method in the &lt;em&gt;Functions&lt;/em&gt; class.&amp;nbsp; Decorate the new method with&lt;em&gt; [NoAutomaticTrigger]&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;For reference here is the Program that I started with.&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;internal class Program
{
    public static void Main(string[] args)
    {
        var task = new OfflineTask(new NotificationService(), new WorkDataSource());

        task.DoTask();
    }
}
&lt;/pre&gt;&lt;p&gt;Here is the &lt;em&gt;Functions&lt;/em&gt; class that I created to replicate it&#39;s functionality. You&#39;ll notice that I&#39;m using manual dependency injection to allow this to be testable. Don&#39;t let that throw you. I think it&#39;s a good idea, but I could have just copy the contents of &lt;em&gt;Main&lt;/em&gt; and pasted them directly into the &lt;em&gt;Execute&lt;/em&gt; method. Note also that &lt;em&gt;Execute&lt;/em&gt; now has a &lt;em&gt;TextWriter&lt;/em&gt; parameter named &lt;em&gt;log&lt;/em&gt;. This is the hook into the WebJobs logging facility. For now, we just add log messages that we are starting and finishing. You can continue to use whatever logging you already have in place. If you choose to integrate with the WebJobs logging you can by passing the &lt;em&gt;log&lt;/em&gt; parameter to your classes/methods as needed. There are also ways to connect this log facility to an existing one but that&#39;s beyond the scope of this article.&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;internal class Functions
{
    private readonly NotificationService _notificationService;
    private readonly WorkDataSource _workDataSource;

    public Functions()
        : this (new NotificationService(), new WorkDataSource())
    {
        
    }

    public Functions(NotificationService notificationService, WorkDataSource workDataSource)
    {
        _notificationService = notificationService;
        _workDataSource = workDataSource;
    }

    [NoAutomaticTrigger]
    public void Execute(TextWriter log)
    {
        log.WriteLine(&quot;starting job&quot;);

        var task = new OfflineTask(_notificationService, _workDataSource);

        task.DoTask();

        log.WriteLine(&quot;job completed&quot;);
    }
}
&lt;/pre&gt;&lt;p&gt;Now that we have our functions created, we’ll modify the &lt;em&gt;Main&lt;/em&gt; method to set up a &lt;em&gt;JobHost&lt;/em&gt; and use it to invoke our new &lt;em&gt;Execute&lt;/em&gt; method. Before we do that, though, we need to add some configuration values. We need connection strings for the WebJobs dashboard and for WebJobs storage, by convention these are named &lt;em&gt;AzureWebJobsDashboard&lt;/em&gt; and &lt;em&gt;AzureWebJobsStorage&lt;/em&gt;. I recommend that you store these in a file that is not checked into source control and reference it from your &lt;em&gt;App.Config&lt;/em&gt; file.&lt;/p&gt;&lt;p&gt;Create or use an existing storage account. Copy the connection strings from the Azure portal and add them to your connection strings.&lt;/p&gt;&lt;pre class=&quot;brush: xml;&quot;&gt;&amp;lt;connectionStrings&amp;gt;
  &amp;lt;add name=&quot;AzureWebJobsDashboard&quot; connectionString=&quot;your-connnection-string-copied-from-Azure&quot;/&amp;gt;
  &amp;lt;add name=&quot;AzureWebJobsStorage&quot; connectionString=&quot;your-connnection-string-copied-from-azure&quot;/&amp;gt;
&amp;lt;/connectionStrings&amp;gt;
&lt;/pre&gt;&lt;p&gt;Now, in your &lt;em&gt;Main&lt;/em&gt; method, remove the code you copied over to &lt;em&gt;Functions.Execute&lt;/em&gt; and insert the code to create a &lt;em&gt;JobHostConfiguration&lt;/em&gt;, then a &lt;em&gt;JobHost&lt;/em&gt; using that configuration. Then use reflection to get the method or methods that you want to execute when the program is run from your &lt;em&gt;Functions&lt;/em&gt; class.&amp;nbsp; For each of these methods, use the &lt;em&gt;Call&lt;/em&gt; method on the &lt;em&gt;JobHost&lt;/em&gt; to invoke the method.&amp;nbsp; The &lt;em&gt;JobHost&lt;/em&gt; knows to add the &lt;em&gt;TextWriter&lt;/em&gt; to the parameters when calling the method.&amp;nbsp; You can also supply a custom activator to the JobHostConfiguration so that you can hook into your favorite dependency injection framework if you want.&amp;nbsp; There’s an &lt;a href=&quot;https://github.com/tvanfosson/azure-web-jobs-demo/blob/master/WebJobsDemo/StatisticsRecalculationWebJob/Program.cs&quot;&gt;example&lt;/a&gt; of this in my WebJobs talk demonstration code.&lt;/p&gt;&lt;p&gt;Here’s the updated Program code after changing it to invoke the Function as a WebJob.&lt;/p&gt;&lt;pre class=&quot;brush: xml;&quot;&gt;internal class Program
{
    public static void Main(string[] args)
    {
        var config = new JobHostConfiguration();

        var host = new JobHost(config);

        var tasks = typeof(Functions).GetMethods()
                                     .Where(m =&amp;gt; m.GetCustomAttributes(typeof(NoAutomaticTriggerAttribute), false).Any());
        foreach (var method in tasks)
        {
            host.Call(method);
        }
    }
}
&lt;/pre&gt;&lt;p&gt;Lastly, to get the job to run on a schedule, add a settings.json file as a Content item (I use Copy Always) to the project specifying when the job should run. This is used by the scheduler in &lt;a href=&quot;https://github.com/projectkudu/kudu/wiki/Web-jobs&quot;&gt;Kudu&lt;/a&gt;, the underlying framework that manages WebJobs. It has a relatively simple format. The only property we are going to set is the &quot;schedule&quot; - that&#39;s always been enough for me. The &quot;schedule&quot; property is a cron-like entry ({second} {minute} {hour} {day} {month} {day of the week}) specifying (in UTC) when to run the program. The following example runs the WebJob at 5AM UTC every day.&lt;/p&gt;&lt;pre class=&quot;brush: xml;&quot;&gt;{ &quot;schedule&quot; : &quot;0 0 5 * * *&quot; }
&lt;/pre&gt;&lt;h1&gt;Add the WebJob to the WebApp&lt;/h1&gt;&lt;p&gt;Now that we have both the Web App and the WebJob set up, we just need to add the WebJob to the WebApp so that when we publish the WebApp, the WebJob is published as well and will run on its schedule.&lt;/p&gt;&lt;p&gt;Right-click on the host project, I named it WebJob.Host, then choose Add, then choose Add Existing Project as Azure WebJob.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghIma4sgROmbXv2szvaiUzLjqWYSAqO8HXrbwMwb5FKV76wSkpM-qDcDRXIAPEMmWcG7erY2z9HiV-qTz7XcwKv6HW0BR7rykRXjCLNRRYZxjPQqTqJlWUw8SmUNfB08zDFIgkks3sl4Y/s1600-h/AddWebJobToHost%255B4%255D&quot;&gt;&lt;img title=&quot;AddWebJobToHost&quot; style=&quot;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&quot; border=&quot;0&quot; alt=&quot;AddWebJobToHost&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4_98PcKcu4EThUFRsCIogX_rwXJc1wBY2BOGDtO8seh40Ad7K71M7FOQx8E5Tp0NcFrtI-1W4Y_rI2W2gQgkJXaXXzZJXBNd7tZrMrpHezOJ-e9xDvDy2BdQRQLUiQj7EUo6-I5WF23M//?imgmax=800&quot; width=&quot;538&quot; height=&quot;458&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;This brings up a configuration Wizard. Choose the project you want to add, give it the name you want to see in the Azure console – there are some name restrictions, for example you can’t use dots in the WebJob name. Set the run mode to &lt;em&gt;OnDemand&lt;/em&gt; – our schedule is included in the &lt;em&gt;settings.json&lt;/em&gt; file so we don’t need to set a schedule here. Click OK to add the WebJob to the WebApp.&lt;/p&gt;&lt;p&gt;This will install the WebJobs publishing package. It adds a &lt;em&gt;webjobs-list.json&lt;/em&gt; file in the &lt;em&gt;Properties&lt;/em&gt; folder of your Web App.&amp;nbsp; This lists the jobs that get published with the Web App and their relative location in the project. It also adds a &lt;em&gt;webjob-publish-settings.json&lt;/em&gt; file to your WebJob project, again in the &lt;em&gt;Properties&lt;/em&gt; folder. You might see some JSON validation errors in this file. I haven’t found these to cause problems when deployed, but I generally clean up the unused properties to remove the errors.&lt;/p&gt;&lt;p&gt;Now, we’re essentially done. Verify your configuration values and publish your host WebApp. Check, using the Azure portal – see the WebJob pane in settings – to make sure your job was deployed and will be run on the schedule that you’ve chosen. Use the Logs to view the log messages written to the &lt;em&gt;TextWriter&lt;/em&gt;. You can also access Kudu directly via the Tools pane on the Web App to dig deeper to test and debug your Web Job.&lt;/p&gt;&lt;p&gt;Code used for this post can be found on &lt;a href=&quot;https://github.com/tvanfosson/ConsoleAppToWebJob&quot;&gt;GitHub&lt;/a&gt;. Note that both the original console app and the converted app (now WebJob) are included in the code so you can compare the before and after conversion states. You would probably only have the single project, converted in place, in your solution.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/2835739695430079211/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2016/08/converting-console-application-to-azure.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/2835739695430079211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/2835739695430079211'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2016/08/converting-console-application-to-azure.html' title='Converting a Console Application to an Azure WebJob'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjh-JBDSvS0fq_zSd5T-sGTIhEahCOdIpCfme_JGwjZOnWd50IxbYZ3Nca12uR2d0-IGTlOFn_AOu5jmEX2wAEPrQrEuwnijCSeLhyNLOvNb57p3mT8C_4QHMfHQwkxqFr7INb1g4oqP_g/s72-c/?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-7728648333377642288</id><published>2016-07-24T10:17:00.001-05:00</published><updated>2016-07-24T10:17:46.171-05:00</updated><title type='text'>Why are Estimates Often Wrong: A Response</title><content type='html'>This article, &lt;a href=&quot;http://www.michaelrwolfe.com/2013/10/19/50/&quot;&gt;Why are software estimates regularly off by a factor of 2-3 times?&lt;/a&gt; showed up in my Twitter feed today It was billed as one of the best explanations of the &quot;futility of software estimation.&quot; Go read it now or the rest of this won&#39;t make much sense.  I&#39;ll wait....  ok, now that you&#39;re back...  While I&#39;m generally in agreement with the #NoEstimates folks (movement?), I don&#39;t agree with that description of the problem as being the root cause as a general rule. Yes, it might, maybe even probably, applies in the context in which it was written - start ups. That doesn&#39;t include most of us. When I push back on giving an estimate, using that as my defense is going to get me laughed out of the room.&lt;br /&gt;
&lt;br /&gt;
The article lays out a fictitious trip between SF and LA with the narrator looking at a map and using a basic rule of thumb on velocity and the &quot;as the crow flies&quot; distance between SF and LA to come up with an estimate of 10 days to make the trip. The basic premise of the article is that we can&#39;t estimate what we don&#39;t know. That is absolutely true. But there are some other things that are true as well, especially if you can&#39;t avoid making the estimate (and I agree, working in a way that makes estimates unnecessary is the ideal, it&#39;s just not always possible).&lt;br /&gt;
&lt;br /&gt;
Here&#39;s one truth. You should find someone who has made the trip, or one like it. Have them tell you how long they think it will take. Better yet, have someone who has made the trip several times, with different people, under different conditions. Even better find several such people - with different backgrounds (skills). Put them all in a room to talk about their experiences as it relates to this trip, then have them all come to consensus on what they think it will take.&lt;br /&gt;
&lt;br /&gt;
Here&#39;s another. If you truly can&#39;t find anyone with experience with a particular journey: don&#39;t give an estimate on how long the whole journey will take until you&#39;ve actually done part of it. In particular, if you can see some spots on the map that look like they might be difficult, do some (not necessarily all) of those parts. Then, revisit your estimate. Ok, you still won&#39;t be accurate - but you should be &lt;i&gt;more&lt;/i&gt; accurate. At the very least, you&#39;ll be more likely to over-estimate than under-estimate if you base it on experience with what you think are the difficult parts.&lt;br /&gt;
&lt;br /&gt;
Another truth. There were a lot of unstated assumptions in that story. The road is flat. The road is smooth. There are no obstacles. No one will need a break during the trip. Anyone who has done any hiking before - in CA or not, along the coast or not - will be able to tell you that those assumptions are unrealistic. Expose those assumptions and they become readily apparent. If the narrator had told his friends how long he thought it would take AND the conditions under which he was making his estimate, I&#39;m guessing the friends push back on the estimate as unrealistic. At the very least, you&#39;ve given yourself (and them) the ability to evaluate your assumptions and test them.&lt;br /&gt;
&lt;br /&gt;
Finally, though I could probably go on, if you give an estimate that allows you to mark a particular day on the calendar instead of range of days, you&#39;re treating your estimate as a measurement. Estimates should be ranges, not numbers. They should also be held loosely. Yes, go ahead and make plans based on your ranges, but expect to adjust those plans as you gain experience and improve your estimates on the remaining work. It should not come as a surprise that your plans have to change.&lt;br /&gt;
&lt;br /&gt;
In my experience, there are many reasons why estimates are wrong - failing to account for the unexpected is only one of them and shouldn&#39;t be the primary reason. People with experience usually factor that into their estimate. The one unexpected that you can&#39;t account for and which will trip you up the most is when the destination changes mid-trip. When you are faced with a situation where you&#39;re not sure where you are going - and start-up land or new product development can be one of those places - avoid estimates for anything longer than the immediate work in front of you. If you can live without them entirely, do so.  If you can&#39;t, then use experience, spikes, exposing assumptions, and ranges rather than numbers, to help make the necessary estimates and use them appropriately.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/7728648333377642288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2016/07/why-are-estimates-often-wrong-response.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/7728648333377642288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/7728648333377642288'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2016/07/why-are-estimates-often-wrong-response.html' title='Why are Estimates Often Wrong: A Response'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-7019741586202771569</id><published>2015-10-24T14:06:00.001-05:00</published><updated>2015-11-09T10:16:42.018-06:00</updated><title type='text'>Twin Cities Code Camp: Presentation </title><content type='html'>Links to information used in my presentation on Automated Testing: Patterns and Practices&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://github.com/tvanfosson/talks/tree/master/TCCC19&quot;&gt;Slides&lt;/a&gt; (&lt;a href=&quot;https://speakerdeck.com/tvanfosson/automated-testing-patterns-and-practices&quot;&gt;SpeakerDeck&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://farm-fresh-code.blogspot.com/2014/02/lightweight-integration-testing-with.html&quot;&gt;Lightweight Integration Testing with Dapper&lt;/a&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://github.com/tvanfosson/dapper-integration-testing&quot;&gt;Dapper Example Repository&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/7019741586202771569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2015/10/twin-cities-code-camp-presentation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/7019741586202771569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/7019741586202771569'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2015/10/twin-cities-code-camp-presentation.html' title='Twin Cities Code Camp: Presentation '/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-261828806136242732</id><published>2015-03-07T16:49:00.000-06:00</published><updated>2015-03-09T09:11:31.184-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC"/><category scheme="http://www.blogger.com/atom/ns#" term="Git"/><category scheme="http://www.blogger.com/atom/ns#" term="MSBuild"/><title type='text'>Convention-Driven Automatic Release Versioning from Your Git Repo</title><content type='html'>&lt;h2&gt;Introduction&lt;/h2&gt;I have a project where I wanted to automatically generate some information about what version has been deployed so I can ensure that, post-deploy, the correct version has been deployed to production easily.&amp;nbsp; For my purposes, I chose to use a mechanism that depends on semantic versioning of the Git release branches to avoid having to maintain version numbers inside my project. That is, assuming that my Git release branches follow a naming standard that incorporates the version of the code, I wanted to use the branch name and some other information to identify the version in the deployed application.&lt;br /&gt;
&lt;br /&gt;
I found an article, &lt;a href=&quot;http://dotnetninja.de/2013/06/unobtrusive-msbuild-using-git-information-in-your-assemblies/&quot; target=&quot;_blank&quot;&gt;Unobtrusive MSBuild: Using Git information in your assemblies&lt;/a&gt;, that was slightly more complex than I wanted describing how to do this with MSBuild Community tasks. Using information from the article and simplifying it some I was able to develop a fairly straight-forward way of building an &lt;em&gt;AssemblyInformationalVersionAttribute&lt;/em&gt; attribute with the Git branch name, commit hash, and the build time.&lt;br /&gt;
&lt;br /&gt;
Using the &quot;unobtrusive approach&quot; described in the article, this is generated in a separate, unversioned file that is re-created on every build(&lt;em&gt;Properties/AutoGeneratedAssemblyInfo.cs&lt;/em&gt;). When done for a release it will reflect the branch being used for the release deployment. The file is removed when the project is cleaned.&amp;nbsp; Note: it&#39;s important that this file be excluded from your Git repo as it changes on every build - no sense in checking in a file that is auto-generated anyway.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Process&lt;/h2&gt;&lt;ol&gt;&lt;li&gt;Update your &lt;em&gt;.gitignore&lt;/em&gt; file to exclude files named &quot;&lt;em&gt;GeneratedAssemblyInfo.cs&lt;/em&gt;&quot;. Commit this change so that the automatically generated files we will be creating will not be added to the repository.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Unload your project and open the project file in the editor.&amp;nbsp; Right-click on the project name in Visual Studio and select &lt;strong&gt;Unload Project&lt;/strong&gt;. Right-click again on the (unloaded) project and select &lt;strong&gt;Edit &amp;lt;project-name&amp;gt;&lt;/strong&gt;.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Install MSBuildTasks NuGet package into the project. The original author added a separate “dummy” build project to the solution. I found that adding it to an existing project works equally well. This will add a &lt;em&gt;.build&lt;/em&gt; folder to your solution with the MSBuild Community tasks and targets. &lt;br /&gt;
&lt;br /&gt;
Note: you may need to set the PowerShell Execution Policy for this to work. I found that I needed to set the 32-bit PS Execution Policy to &lt;strong&gt;RemoteSigned&lt;/strong&gt; on my 64-bit system as well using: &lt;pre class=&quot;brush: ps; toolbar: false;&quot;&gt;start-job { Set-ExecutionPolicy Unrestricted } -RunAs32 | wait-job | Receive-Job 
&lt;/pre&gt;&lt;br /&gt;
This needs to be executed from a PowerShell console window running as administrator. &lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Add a Project Group to your &lt;em&gt;.csproj&lt;/em&gt; referencing the community tasks that you just added. This property group defines the path to the community tasks folder, relative to the solution directory, the path of the generated assembly info file, the assembly copyright condition and extends the build/clean item groups so that the targets that we will define later are called at the appropriate times.&lt;pre class=&quot;brush: xml; toolbar: false;&quot;&gt;&amp;lt;PropertyGroup&amp;gt;
  &amp;lt;MSBuildCommunityTasksPath&amp;gt;$(SolutionDir)\.build&amp;lt;/MSBuildCommunityTasksPath&amp;gt;
  &amp;lt;GeneratedAssemblyInfoFile Condition=&quot; &#39;$(GeneratedAssemblyInfoFile)&#39; == &#39;&#39; &quot;&amp;gt;$(MsBuildProjectDirectory)\Properties\GeneratedAssemblyInfo.cs&amp;lt;/GeneratedAssemblyInfoFile&amp;gt;
  &amp;lt;AssemblyCopyright Condition=&quot;&#39;$(AssemblyCopyright)&#39; == &#39;&#39;&quot;&amp;gt;
  &amp;lt;/AssemblyCopyright&amp;gt;
  &amp;lt;BuildDependsOn&amp;gt;
    SetAssemblyVersion
    $(BuildDependsOn)
  &amp;lt;/BuildDependsOn&amp;gt;
  &amp;lt;CleanDependsOn&amp;gt;
    $(CleanDependsOn)
    SetAssemblyVersionClean
  &amp;lt;/CleanDependsOn&amp;gt;
  &amp;lt;TargetFrameworkProfile /&amp;gt;
&amp;lt;/PropertyGroup&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Import the MSBuild Community task targets. Note original article describes also having to define a &lt;em&gt;UsingTask&lt;/em&gt; for the Git branch command. I found that this already existed in the version of the community targets I was using, 1.4.0.88. Add the following directive with your other &lt;em&gt;Import&lt;/em&gt; directives.&lt;pre class=&quot;brush: xml; toolbar: false;&quot;&gt;&amp;lt;Import Project=&quot;$(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.Targets&quot; /&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Add the &lt;em&gt;SetAssemblyVersion&lt;/em&gt; target which actually builds the &lt;em&gt;GeneratedAssemblyInfo.cs&lt;/em&gt; file with the &lt;em&gt;AssemblyInformtionalVersion&lt;/em&gt; attribute applied to the assembly being built.  Also add a &lt;em&gt;BeforeBuild&lt;/em&gt; target that depends on the &lt;em&gt;SetAssemblyVersion&lt;/em&gt; target you just added to make sure that it is invoked.  Note: the build target below is simplified from the original article to include only those aspects of the Git information that are to be used and does not include any manually maintained version information or build computer information as that was not necessary for my requirements.&lt;pre class=&quot;brush: xml; toolbar: false;&quot;&gt;&amp;lt;Target Name=&quot;BeforeBuild&quot; DependsOnTargets=&quot;SetAssemblyVersion&quot;&amp;gt;
&amp;lt;/Target&amp;gt;
&amp;lt;Target Name=&quot;SetAssemblyVersion&quot;&amp;gt;
&amp;lt;PropertyGroup&amp;gt;
  &amp;lt;BuildTime&amp;gt;$([System.DateTime]::UtcNow.ToString(&quot;yyyy-MM-dd HH:mm:ss&quot;))&amp;lt;/BuildTime&amp;gt;
  &amp;lt;AssemblyCopyrightText Condition=&quot; &#39;$(AssemblyCopyright)&#39; != &#39;&#39; &quot;&amp;gt;$(AssemblyCopyright) $([System.DateTime]::UtcNow.Year)&amp;lt;/AssemblyCopyrightText&amp;gt;
  &amp;lt;AssemblyCopyrightText Condition=&quot; &#39;$(AssemblyCopyrightText)&#39; == &#39;&#39; &quot;&amp;gt;
  &amp;lt;/AssemblyCopyrightText&amp;gt;
&amp;lt;/PropertyGroup&amp;gt;
&amp;lt;GitVersion LocalPath=&quot;$(SolutionDir)&quot;&amp;gt;
  &amp;lt;Output TaskParameter=&quot;CommitHash&quot; PropertyName=&quot;CommitHash&quot; /&amp;gt;
&amp;lt;/GitVersion&amp;gt;
&amp;lt;Message Importance=&quot;High&quot; Text=&quot;Commit is $(CommitHash)&quot; /&amp;gt;
&amp;lt;GitBranch LocalPath=&quot;$(SolutionDir)&quot;&amp;gt;
  &amp;lt;Output TaskParameter=&quot;Branch&quot; PropertyName=&quot;GitBranch&quot; /&amp;gt;
&amp;lt;/GitBranch&amp;gt;
&amp;lt;Message Importance=&quot;High&quot; Text=&quot;Branch is $(GitBranch)&quot; /&amp;gt;
&amp;lt;AssemblyInfo CodeLanguage=&quot;CS&quot; OutputFile=&quot;$(GeneratedAssemblyInfoFile)&quot; AssemblyInformationalVersion=&quot;$(GitBranch)-$(CommitHash), built $(BuildTime) UTC&quot; AssemblyCopyright=&quot;$(AssemblyCopyrightText)&quot; /&amp;gt;
&amp;lt;/Target&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Add the &lt;em&gt;SetAssemblyVersionClean&lt;/em&gt; target to delete the generated assembly info file when the project is cleaned.&lt;pre class=&quot;brush: xml; toolbar: false;&quot;&gt;&amp;lt;Target Name=&quot;SetAssemblyVersionClean&quot; Condition=&quot;Exists($(GeneratedAssemblyInfoFile))&quot;&amp;gt;
  &amp;lt;Delete Files=&quot;$(GeneratedAssemblyInfoFile)&quot; /&amp;gt;
&amp;lt;/Target&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Add a compile directive to the &lt;em&gt;ItemGroup&lt;/em&gt; containing your other compile directives for the generated file.&lt;pre class=&quot;brush: xml; toolbar: false;&quot;&gt;&amp;lt;Compile Include=&quot;$(GeneratedAssemblyInfoFile)&quot; /&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Save your changes to the project file, close, and reload the project in your solution.  Build the solution. Observe in the build output that the commit hash and branch information messages specify the current values.&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;h2&gt;Usage&lt;/h2&gt;In my project I have a &lt;em&gt;MaintenanceController&lt;/em&gt; that is restricted to administrators. This controller outputs a maintenance page with information about the current version and other system information. The version is obtained from the &lt;em&gt;AssemblyInformationalVersionAttribute&lt;/em&gt; we created.  &lt;br /&gt;
&lt;pre class=&quot;brush: csharp; toolbar: false;&quot;&gt;using System.Linq;
using System.Reflection;
using System.Web.Mvc;
using System.Web.UI;

using MyProject.Web.ViewModels;

namespace MyProject.Web.Controllers
{
    [Authorize(Roles = Role.ADMIN)]
    public class MaintenanceController : Controller
    {
        private static readonly string _currentProductionTag;
        private const int ONE_DAY = 60 * 60 * 24;

        static MaintenanceController()
        {
            try
            {
                _currentProductionTag = Assembly.GetExecutingAssembly()
                                               .GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false)
                                               .OfType&amp;lt;AssemblyInformationalVersionAttribute&amp;gt;()
                                               .First()
                                               .InformationalVersion;
            }
            catch
            {
                _currentProductionTag = &quot;Unknown&quot;;
            }
        }

        [HttpGet]
        [OutputCache(Location = OutputCacheLocation.Server, Duration = ONE_DAY)]
        public ActionResult Index()
        {
            return View(new MaintenanceIndexViewModel()
            {
                CurrentProductionTag = _currentProductionTag,
                // other information
            });
        }

    }
}
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/261828806136242732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2015/03/convention-driven-automatic-release.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/261828806136242732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/261828806136242732'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2015/03/convention-driven-automatic-release.html' title='Convention-Driven Automatic Release Versioning from Your Git Repo'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-8041951729449958054</id><published>2014-12-27T14:03:00.001-06:00</published><updated>2015-03-07T16:39:51.857-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Entity Framework"/><category scheme="http://www.blogger.com/atom/ns#" term="LINQtoSQL"/><title type='text'>Converting a Legacy LINQ-to-SQL Data Context to Entity Framework</title><content type='html'>Recently I worked with a client to upgrade their web application to use the latest technology available for ASP.NET MVC. This included upgrading the .NET framework, upgrading existing NuGet packages (and using packages to replace libraries tracked in SCM), and replacing custom code that duplicated current framework features. The largest change, however, was to upgrade the data access layer to use a combination of Entity Framework and Dapper instead of LINQ-to-SQL (L2S). Because this is client code I&#39;m only including a few isolated snippets and not a link to the repository in this article.&lt;br /&gt;
&lt;br /&gt;
While there are many similarities between L2S&#39;s DataContext and Entity Framework&#39;s DbContext implementations, there are enough gotchas that it became more of an ordeal than I had anticipated.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Reverse Engineering the Model&lt;/h3&gt;I started out by using the &lt;a href=&quot;http://msdn.microsoft.com/en-us/data/jj593170.aspx&quot; target=&quot;_blank&quot;&gt;Entity Framework Power Tools&lt;/a&gt; to reverse engineer the existing database. I did this into a separate solution to avoid conflicts with the existing model classes and data context. Once you&#39;ve added the power tools you will get an Entity Framework option with some new sub-options when you right-click on a project. I used the Entity Framework -&amp;gt; Reverse Engineer Code First power tool to generate the model classes, fluent mappings, and DbContext implementation.&lt;br /&gt;
&lt;br /&gt;
Once I had the model reverse engineered, I manually adapted the reverse engineered classes to reflect the changes made to the L2S model over time.&amp;nbsp; This included adding some short cut properties – say to find the first item in a collection – and convenience methods.&amp;nbsp; I’ll note here that my goal was to do an “in-place” upgrade, not refactor the architecture. Even though there were places that refactoring would improve the code I felt that it was too risky to attempt much refactoring AND swap the underlying data access technology at the same time. There were only&amp;nbsp; a few places where there was some obvious code duplication that I ended up changing in this way; mostly I simply translated the code from the L2S classes to the EF classes. Because I was doing this in a separate solution this involved copying some code over from the existing solution where the existing models referenced types outside of the model.&amp;nbsp; Mostly these were enumerated types (enums) that were used for some model properties. By and large the model classes were well-isolated from the rest of the solution.&amp;nbsp; The fact that the previous developers followed good principles made the transition much easier.&lt;br /&gt;
&lt;br /&gt;
Even so, there were a few areas of “gotchas” where the design choices in EF didn’t match those in L2S that caused me problems.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Configuring Relations&lt;/h3&gt;This was probably the largest area of difficulty that I faced. There were 3 distinct types of mapping issues that I had with relations. First, not all of the relations in the previous model had been mapped. In those cases I simply removed the mapped relation from the reverse-engineered models. Since my goal was to replicate existing behavior this seemed like the obvious choice. Later, when we start doing optimizations on the EF code, some of these may be added back if needed to improve query performance.&lt;br /&gt;
&lt;br /&gt;
Second, some relations were mapped as one-to-many using the EF tooling that had been mapped one-to-one in L2S. These were trickier to deal with because of some missing capabilities in the fluent mapping methods.&amp;nbsp; With a one-to-many mapping, the fluent EF tooling allows you to include both the navigation property and the column housing the foreign key in the model. That’s not true – or at least I could not find a way to do it – for one-to-one/zero. In those cases, the methods that allow you to specify the foreign key correlation to an model property do not exist and if you try to include the FK property, you get a column exists conflict on the model.&lt;br /&gt;
I handled these in two ways. If the FK property wasn’t used outside the model class, I defaulted to removing the FK property and setting the property up as one-to-one/zero in the model using WithRequired(t =&amp;gt; t.NavProperty).WithOptional(t =&amp;gt; t.InverseNavProperty), specifying a custom key as necessary with .Map().&amp;nbsp; If the FK property was used outside the class – which you might do in order to avoid a subquery to get the related data – I left the property mapped one-to-many and added a convenience property to find the FirstOrDefault() in the collection to replace the existing one-to-one/zero mapping. This necessitated some code changes to set up the relations but these seemed straightforward and involved the least amount of disruption to existing code.&amp;nbsp; This introduced some properties that needed to be ignored explicitly on the model, but more on that later.&lt;br /&gt;
&lt;br /&gt;
Lastly, I ran into some issues with many-to-many mappings. These included many-to-many mappings that did not follow the Entity Framework convention for foreign keys. Entity Framework expects foreign keys on join tables and join tables that included extra data. These seemed particularly difficult to deal with, though I came to find eventually that what I thought were join table mapping issues were really caused by some navigation properties that had not been ignored.&amp;nbsp;&amp;nbsp; L2S uses a paradigm where the mappings have to be manually added to the model. EF uses a convention-based mechanism where it applies a default mapping unless you’ve explicitly overridden or ignored it.&amp;nbsp; This mismatch caused a lot of confusion at first as the reverse engineering tool had set up all of the mappings. In the process of resolving the issues above I had inadvertently introduced some model errors with the convenience properties.&lt;br /&gt;
&lt;br /&gt;
With respect to those places where the keys did not match the expected conventions, I ended up explicitly mapping the foreign keys using .Map() and specifying the appropriate key values. This also involved some code changes where I had to remove the join table model that had existed in the L2S model since L2S did not handle many-to-many mappings directly but only as bidirectional one-to-many mappings from each side to the join table.&amp;nbsp; When there was additional data in the join table, I left the join table model in the solution and set it up as the bidirectional one-to-many association.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Sample Many-to-Many Modeled as Two One-to-Many Relations &lt;/h2&gt;&lt;pre class=&quot;brush: csharp; toolbar: false;&quot;&gt;public class UserClientMap : EntityTypeConfiguration&amp;lt;UserClient&amp;gt;
{
    // model simplified

    HasKey(t =&amp;gt; t.Id);

    Property(t =&amp;gt; t.Id).HasColumn(&quot;Id&quot;);
    Property(t =&amp;gt; t.IsPrimaryContact).HasColumn(&quot;IsPrimaryContact&quot;);
    Property(t =&amp;gt; t.UserId).HasColumn(&quot;UserId&quot;);
    Property(t =&amp;gt; t.ClientId).HasColumn(&quot;ClientId&quot;);

    HasRequired(t =&amp;gt; t.Client)
        .WithMany(t =&amp;gt; t.UserClients)
        .HasForeignKey(t =&amp;gt; t.ClientId);

    HasRequired(t =&amp;gt; t.User)
        .WithMany(t =&amp;gt; t.UserClients)
        .HasForeignKey(t =&amp;gt; t.UserId);
}&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;Excluding Properties&lt;/h3&gt;&lt;br /&gt;
The existing model included some properties that were not persisted. I had made an initial assumption that if these weren&#39;t mapped in the fluent mappings, they would be automatically excluded since all of the properties in the database had been mapped in the reverse engineered mapping files. This turned out to be a false assumption; I haven&#39;t used the fluent mappings much and haven&#39;t internalized their idiosyncrasies. I had also made the assumption that properties without setters, the convenience properties from above, would also be ignored. That also turned out to be false.&lt;br /&gt;
&lt;br /&gt;
I began to set up the properties causing model errors manually using .Ignore(). This would work, but given the size of the model my laziness prevailed and I tried to find a way that I could use conventions that would allow me to use less code per mapping class and help prevent errors caused by failing to update the mapping file when a model changed to add a property that should be ignored.&lt;br /&gt;
&lt;br /&gt;
I landed on an extension method to the EntityTypeConfiguration class coupled with the use of NotMappedAttribute found in the System.ComponentModel.DataAnnotations.Schema namespace.&lt;br /&gt;
&lt;br /&gt;
The extension class has a method, ExludeIgnoredProperties, that enforces two conventions by adding an Ignore() for the property if it contains no setter method or if it is marked with the NotMappedAttribute. Each mapping class adds a call to &lt;span style=&quot;font-family: Consolas; font-size: x-small;&quot;&gt;this.ExcludeIgnoredProperties();&lt;/span&gt; and both of these conventions are enforced for this model. Because each property has a different type I ended up using &quot;dynamic&quot; to allow the correctly typed lambda expression to be returned when constructing the argument for the Ignore() method.&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; toolbar: false;&quot;&gt;internal static class EntitytTypeConfigurationExtensions
{
    public static void ExcludeIgnoredProperties&amp;lt;T&amp;gt;(this EntityTypeConfiguration&amp;lt;T&amp;gt; configuration)
        where T : class
    {
        foreach (var expression in GetIgnoredProperties&amp;lt;T&amp;gt;())
        {
            configuration.Ignore(expression);
        }
    }

    private static IEnumerable&amp;lt;dynamic&amp;gt; GetIgnoredProperties&amp;lt;T&amp;gt;()
        where T : class
    {
        var type = typeof(T);
        var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);


        foreach (var expression in GetPropertiesWithoutSetters&amp;lt;T&amp;gt;(properties))
        {
            yield return expression;
        }

        foreach (var expression in GetExcludedProperties&amp;lt;T&amp;gt;(properties))
        {
            yield return expression;
        }
    }

    private static IEnumerable&amp;lt;dynamic&amp;gt; GetPropertiesWithoutSetters&amp;lt;T&amp;gt;(IEnumerable&amp;lt;PropertyInfo&amp;gt; properties)
        where T : class
    {
        var type = typeof(T);
        foreach (var propertyInfo in properties)
        {
            var setter = propertyInfo.GetSetMethod();
            if (setter == null)
            {
                var parameter = Expression.Parameter(type, &quot;t&quot;);
                var body = Expression.Property(parameter, propertyInfo);
                var lambda = Expression.Lambda(body, parameter);
                yield return lambda;
            }
        }
    }

    private static IEnumerable&amp;lt;dynamic&amp;gt; GetExcludedProperties&amp;lt;T&amp;gt;(IEnumerable&amp;lt;PropertyInfo&amp;gt; properties)
        where T : class
    {
        var type = typeof(T);
        foreach (var propertyInfo in properties)
        {
            var ignoreAttribute = propertyInfo.GetCustomAttribute&amp;lt;NotMappedAttribute&amp;gt;();
            if (ignoreAttribute != null)
            {
                var parameter = Expression.Parameter(type, &quot;t&quot;);
                var body = Expression.Property(parameter, propertyInfo);
                var lambda = Expression.Lambda(body, parameter);
                yield return lambda;
            }
        }
    }
}&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;Replicating Default LoadWith Behavior&lt;/h3&gt;&lt;br /&gt;
The last major challenge I had was to replicate L2S&#39;s default LoadWith behavior. In L2S, you need to set up all of the included properties before making any queries using the data context. If you don&#39;t an InvalidOperationException is thrown. As a result, the repository implementation defined some properties that automatically got loaded with each model type when the data context was instantiated.&lt;br /&gt;
&lt;br /&gt;
Entity Framework is much more flexible and allows the included relations to be defined per-query, however, I wanted to retain as much of the existing code and behavior as I could. In particular, I needed to retain as much of the efficiency of using included relations as I could without having to re-visit every query performed against the repository&lt;br /&gt;
&lt;br /&gt;
This is probably the area in which my in-place upgrade resulted in the most compromises from what I would normally have implemented. Generally I use a repository per root pattern, but the existing repository was a single generic repository and the &quot;roots&quot; where defined via generic constraints on the model type. Each &quot;root&quot; model type extended an abstract (empty) Root model class and the constraints only allowed a Root class to be the base of a query.&lt;br /&gt;
&lt;br /&gt;
Using a repository-per-root would have allowed me to to easily defined which related entities were loaded by default for each class. With a single, generic repository I would need to use some reflection to achieve the same effect. In addition I wanted to be able to easily override the defaults for specific queries to make them more efficient as needed. Lastly, I wanted to avoid using if/else or switch statements to define the logic. In my mind the included properties should be more closely associated with the model than the repository so I ended up opting for attribute-based definition of the included relations.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;LoadWithAttribute&lt;/h2&gt;&lt;pre class=&quot;brush: csharp; toolbar: false;&quot;&gt;[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public class LoadWithAttribute : Attribute
{
    internal IEnumerable&amp;lt;string&amp;gt; Includes { get; private set; }

    private string _include;

    public string Include
    {
        get { return _include; }
        set
        {
            _include = value;
            Includes = (value ?? &quot;&quot;).Split(new[] { &#39;,&#39; }, StringSplitOptions.RemoveEmptyEntries)
            .Select(s =&amp;gt; s.Trim());
        }
    }

    public LoadWithAttribute(string include)
    {
        Include = include;
    }
}&lt;/pre&gt;&lt;br /&gt;
This attribute is added to each class that needs to have default included properties defined.  It takes a comma-separated string of property names for the related data to include. In the repository, the attribute is obtained by reflection but only if the developer doesn&#39;t supply a set of included properties specific to that query. Note that the signatures include both one without any included properties and one that takes a number of property names via a params. Both of these defer the behavior to an implementation method that takes an IEnumerable&lt;string&gt; of property names. There&#39;s also a signature (not shown) that takes, as params, any number of Func&lt;t object=&quot;&quot;&gt; parameters if the developer wants to specify using strongly-typed properties rather than property names.&lt;/t&gt;&lt;/string&gt;&lt;br /&gt;
&lt;h2&gt;Sample Repository Methods&lt;/h2&gt;&lt;pre class=&quot;brush: csharp; toolbar: false;&quot;&gt;public class Repository : IRepository
{
    // class simplified
    private static readonly ConcurrentDictionary&amp;lt;Type, IEnumerable&amp;lt;string&amp;gt;&amp;gt; _defaultIncludeMap = new ConcurrentDictionary&amp;lt;Type, IEnumerable&amp;lt;string&amp;gt;&amp;gt;();

    public IQueryable&amp;lt;T&amp;gt; All&amp;lt;T&amp;gt;(Expression&amp;lt;Func&amp;lt;T, bool&amp;gt;&amp;gt; filter)
        where T : Root, new()
    {
        return AllImplementation(filter, GetDefaultIncludes&amp;lt;T&amp;gt;());
    }

    public IQueryable&amp;lt;T&amp;gt; All&amp;lt;T&amp;gt;(Expression&amp;lt;Func&amp;lt;T, bool&amp;gt;&amp;gt; filter, params string[] includedProperties)
        where T : Root, new()
    {
        return AllImplementation(filter, includedProperties);
    }


    private IQueryable&amp;lt;T&amp;gt; AllImplementation&amp;lt;T&amp;gt;(Expression&amp;lt;Func&amp;lt;T, bool&amp;gt;&amp;gt; filter, IEnumerable&amp;lt;string&amp;gt; includedProperties)
        where T : Root, new()
    {
        IQueryable&amp;lt;T&amp;gt; dbSet = _context.Set&amp;lt;T&amp;gt;();

        foreach (var property in includedProperties)
        {
            dbSet = dbSet.Include(property);
        }

        return dbSet.Where(filter);
    }

    private static IEnumerable&amp;lt;string&amp;gt; GetDefaultIncludes&amp;lt;T&amp;gt;()
    {
        var includes = _defaultIncludeMap.GetOrAdd(typeof(T), type =&amp;gt;
        {
            var attribute = type.GetCustomAttribute&amp;lt;LoadWithAttribute&amp;gt;();

            return attribute == null
                ? new List&amp;lt;string&amp;gt;()
                : attribute.Includes;
        });

        return includes;
    }
}&lt;/pre&gt;Now, with these things in place I only needed to exercise the code and find the places where L2S supported constructs were used that don&#39;t have translations to EF queries.  I&#39;m still working through this exercise, performing query optimizations as I can to take advantage of the greater flexibility that EF offers.  Fortunately these are relatively easy to spot (they throw exceptions) and, so far, have been relatively easy to find alternative constructs for.</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/8041951729449958054/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/12/converting-legacy-linq-to-sql-data.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/8041951729449958054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/8041951729449958054'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/12/converting-legacy-linq-to-sql-data.html' title='Converting a Legacy LINQ-to-SQL Data Context to Entity Framework'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-9022669568122360053</id><published>2014-11-06T14:07:00.000-06:00</published><updated>2014-11-06T14:07:08.441-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="FakeItEasy"/><category scheme="http://www.blogger.com/atom/ns#" term="mocking"/><category scheme="http://www.blogger.com/atom/ns#" term="TDD"/><category scheme="http://www.blogger.com/atom/ns#" term="testing"/><title type='text'>Action Verification Patterns</title><content type='html'>I was reminded again about a verification pattern that I use frequently when doing TDD/unit tests.  It&#39;s really two different patterns. The first when you want to ensure that some action occurs, the other when you want to make sure it hasn&#39;t.&lt;br /&gt;
&lt;br /&gt;
My examples will be specific to FakeItEasy, but you should be able to extrapolate them to any mocking framework.&lt;br /&gt;
&lt;br /&gt;
The use case for my specific example is the case when you&#39;re creating a new entity via WebAPI and you may be connecting that entity to an existing related entity or creating a new entity for the other end of the relationship as well.  For example, you want to sign up a new user but may be associating that new user with an existing company or, if there is no existing company, create a new one at the same time as you create the user. In this case, among other tests, you&#39;ll want to test that the new company either was or was not created as appropriate.&lt;br /&gt;
&lt;br /&gt;
The patterns come into play in the Assert step of the test. With the mocking framework you ensure that the call across the system boundary, in this case to the database, either did or did not happen. When testing that call was made, use the verification signature that specifies exactly which entity was to have been added.&lt;br /&gt;
&lt;br /&gt;
For example,&lt;br /&gt;
 &lt;br /&gt;
&lt;pre class=&quot;brush: csharp; toolbar: false;&quot;&gt;A.CallTo(() =&amp;gt; _testContext.MockCompanies
                           .Add(A&amp;lt;Company&amp;gt;.That
                                          .Matches(c =&amp;gt; c.Name == expectedCompanyName))
 .MustHaveHappened();&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
The other pattern, when you want to exclude an action, is similar except you use the verification signature that accepts any matching entity.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp; toolbar: false;&quot;&gt;A.CallTo(() =&amp;gt; _testContext.MockCompanies.Add(A&amp;lt;Company&amp;gt;.Ignored))
 .MustNotHaveHappened();&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
In the first, case you make sure that the exact expected instance has really been added to the database. In the second, you ensure that no entity of that type has been added to the database.  By matching on all entities in the second case you avoid an over-specification in which an error in the spec might give you a false positive by failing to match a call because of an error in the condition.  </content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/9022669568122360053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/11/action-verification-patterns.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/9022669568122360053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/9022669568122360053'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/11/action-verification-patterns.html' title='Action Verification Patterns'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-1744277188130096084</id><published>2014-10-29T17:07:00.000-05:00</published><updated>2014-10-29T17:07:35.115-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Autofac"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="extensions"/><title type='text'>Autofac Extensions: It’s the Little Things</title><content type='html'>I get tired of reading, and writing, dependency registrations in Autofac.  Very descriptive, but also very repetitive.  Imagine a large application with a couple of dozen small, focused services each with a registration like:  &lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;builder.RegisterType&amp;lt;DescriptiveService&amp;gt;()
       .As&amp;lt;IDescriptiveService&amp;gt;()
       .InstancePerHttpRequest();&lt;/pre&gt;
&lt;br /&gt;
It&#39;s not a pretty sight.&lt;br /&gt;
&lt;br /&gt;
To make this easy to read and, especially with syntax highlighting, relatively easy to spot errors I created a small extension method as part of my dependency configuration class.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp;&quot;&gt;
public static class DependencyConfig
{
    private static void RegisterPerRequest&amp;lt;TImpl, T&amp;gt;(this ContainerBuilder builder)
        where TImpl : class, T
    {
         builder.RegisterType&amp;lt;TImpl&amp;gt;()
                .As&amp;lt;T&amp;gt;()
                .InstancePerHttpRequest();
    }

    public static void Configure(Action&amp;lt;IDependencyResolver&amp;gt; setResolver)
    {
         var builder = new ContainerBuilder();
         builder.RegisterPerRequest&amp;lt;DescriptiveService,IDescriptiveService&amp;gt;();

         // ...
    }
}&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
I&#39;ll grant you that it works better in a wide window or with shorter class names but I&#39;m happy to not be repeating so much code.  </content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/1744277188130096084/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/10/autofac-extensions-its-little-things.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/1744277188130096084'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/1744277188130096084'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/10/autofac-extensions-its-little-things.html' title='Autofac Extensions: It’s the Little Things'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-6670310080117546341</id><published>2014-05-03T13:17:00.002-05:00</published><updated>2014-05-03T13:27:04.781-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iframe"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><category scheme="http://www.blogger.com/atom/ns#" term="messaging"/><category scheme="http://www.blogger.com/atom/ns#" term="RequireJS"/><title type='text'>Introducing TelegraphJS</title><content type='html'>Long ago, on a very different internet, we used IFrames extensively to layout content where that content might come from many different components on the same system. IFrames are still used but have a very different purpose these days, frequently to include code from various different servers into a seamless experience for the user rather than simply layout various components from the same system.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAMryaZO_LOKgEDe47PE_dvZcKsoowt9inA88CC0WR-G-kIHUBs2oADsegw4qaoAqswNp5jy1AoBlMKSF-QZxIwjyi0wYcm7riCCgsWIdnYXaneLzKqFbKLPenZkyNDlXFsyqr-bgaYuE/s1600/telegraph_train.jpg&quot; imageanchor=&quot;1&quot; style=&quot;float: right; margin-top: 1em; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAMryaZO_LOKgEDe47PE_dvZcKsoowt9inA88CC0WR-G-kIHUBs2oADsegw4qaoAqswNp5jy1AoBlMKSF-QZxIwjyi0wYcm7riCCgsWIdnYXaneLzKqFbKLPenZkyNDlXFsyqr-bgaYuE/s1600/telegraph_train.jpg&quot; height=&quot;186&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;Recently on a project I had a need to use IFrames to provide the ability to embed and interact with content from a different server on a web page. The basic idea is that by including some JavaScript on the page, you create an IFrame “gadget” whose source lives on a different server and a button which allows you to open and close the “gadget” both from a button on the parent page and from inside the “gadget.”&amp;nbsp; I also had a need to trigger some complex behavior within the “gadget” based on the URL parameters found on the request to the parent window.&amp;nbsp; To do this I developed some custom JavaScript that uses &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage&quot; target=&quot;_blank&quot;&gt;postMessage&lt;/a&gt; to communicate between the parent window and the IFrame.&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
After doing this I decided to abstract that code an make a more generalizable framework, which I’ve called &lt;a href=&quot;https://github.com/tvanfosson/telegraphjs&quot; target=&quot;_blank&quot;&gt;TelegraphJS&lt;/a&gt;, that makes it relatively easy to communicate between windows and trigger actions in the other window via callbacks.&amp;nbsp; Partly this was an exercise in creating a module that can be optionally used with or without RequireJS, partly it was because I hadn’t found anything existing that did this. I confess that I didn’t look too hard.&lt;br /&gt;
&lt;br /&gt;
The basic idea is that you would import the &lt;em&gt;telegraph&lt;/em&gt; module (or the the globally available &lt;em&gt;Telegraph&lt;/em&gt; module) to create a new message handler for a specific window.&amp;nbsp; You would optionally register a set of handlers for events (messages) that get passed to the window. Events consist of a unique string, I used the convention “APP:msg” for my events, and a data object for additional information.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Simple Example&lt;/h2&gt;This is a simple example using the global &lt;em&gt;Telegraph&lt;/em&gt; module.&amp;nbsp; An example using RequireJS can be found at &lt;a href=&quot;https://github.com/tvanfosson/telegraphjs&quot; target=&quot;_blank&quot;&gt;https://github.com/tvanfosson/telegraphjs&lt;/a&gt;. This bit creates the parent end of a connection to an IFrame with id &lt;strong&gt;create-frame&lt;/strong&gt;, sets up a handler to receive&lt;em&gt; APP:opened&lt;/em&gt; messages from the IFrame (well, really any IFrame since we haven’t added any security). It then sends an &lt;em&gt;APP:open&lt;/em&gt; message to the IFrame. It&#39;s really only intended to demonstrate the syntax (and I haven&#39;t tried it). To see how it really works, look at the RequireJS example on GitHub.&lt;br /&gt;
&lt;blockquote&gt;&lt;i&gt;I’ll note here that on initialization you may need to repeatedly send any start up messages as the IFrame’s handlers may not yet have been applied. In my use I ended up setting up an interval timer that sent startup up messages until an acknowledgement was received from the child IFRAME. My examples omit the retry behavior.&lt;/i&gt;&lt;/blockquote&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;var&lt;/span&gt; iframe = document.getElementById(&lt;span class=&quot;str&quot;&gt;&#39;client-frame&#39;&lt;/span&gt;);
&lt;span class=&quot;kwrd&quot;&gt;var&lt;/span&gt; contentWindow = iframe.contentWindow;

&lt;span class=&quot;kwrd&quot;&gt;var&lt;/span&gt; handlers = {
    &lt;span class=&quot;str&quot;&gt;&#39;APP:opened&#39;&lt;/span&gt; : &lt;span class=&quot;kwrd&quot;&gt;function&lt;/span&gt;(e, data) {
        alert(&lt;span class=&quot;str&quot;&gt;&#39;opened&#39;&lt;/span&gt;);
    }
};

&lt;span class=&quot;kwrd&quot;&gt;var&lt;/span&gt; telegraph = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Telegraph(contentWindow, handlers);

telegraph.send(&lt;span class=&quot;str&quot;&gt;&#39;APP:open&#39;&lt;/span&gt;);&lt;/pre&gt;The client end of this code is set up the reverse. It receives the &lt;em&gt;APP:open&lt;/em&gt; message and then sends back the &lt;em&gt;APP:opened&lt;/em&gt; message.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;var&lt;/span&gt; telegraph;
&lt;span class=&quot;kwrd&quot;&gt;var&lt;/span&gt; handlers = {
    &lt;span class=&quot;str&quot;&gt;&#39;APP:open&#39;&lt;/span&gt; : &lt;span class=&quot;kwrd&quot;&gt;function&lt;/span&gt;(e, data) {
        telegraph.send(&lt;span class=&quot;str&quot;&gt;&#39;APP:opened&#39;&lt;/span&gt;);
    }
};

telegraph = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Telegraph(window.parent, handlers);&lt;/pre&gt;&lt;br /&gt;
&lt;h2&gt;Additional Features&lt;/h2&gt;The code today is pretty simple, but it also includes the ability to add and remove handlers via &lt;em&gt;on/off&lt;/em&gt; similar to how jQuery event handlers are added.&amp;nbsp; At present it doesn’t accept space-separated events but that’s on my TODO list.</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/6670310080117546341/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/05/introducing-telegraphjs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/6670310080117546341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/6670310080117546341'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/05/introducing-telegraphjs.html' title='Introducing TelegraphJS'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAMryaZO_LOKgEDe47PE_dvZcKsoowt9inA88CC0WR-G-kIHUBs2oADsegw4qaoAqswNp5jy1AoBlMKSF-QZxIwjyi0wYcm7riCCgsWIdnYXaneLzKqFbKLPenZkyNDlXFsyqr-bgaYuE/s72-c/telegraph_train.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-8233520228950038558</id><published>2014-04-28T11:04:00.000-05:00</published><updated>2014-04-28T22:17:39.945-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="TDD"/><category scheme="http://www.blogger.com/atom/ns#" term="testing"/><title type='text'>TDD and Me</title><content type='html'>It will come as no surprise to anyone who knows me but I have a bit of a thing for Test Driven Development (TDD).&amp;nbsp; Recently &lt;a href=&quot;https://twitter.com/dhh&quot; target=&quot;_blank&quot;&gt;@dhh&lt;/a&gt; stirred the developer waters with a provocative post, titled &lt;a href=&quot;http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html&quot; target=&quot;_blank&quot;&gt;TDD is dead. Long live testing.&lt;/a&gt; That set off a firestorm on Twitter (what doesn’t these days) which engendered a response from &lt;a href=&quot;https://twitter.com/unclebobmartin&quot; target=&quot;_blank&quot;&gt;@unclebobmartin&lt;/a&gt;, titled &lt;a href=&quot;http://blog.8thlight.com/uncle-bob/2014/04/25/MonogamousTDD.html&quot; target=&quot;_blank&quot;&gt;Monogamous TDD&lt;/a&gt;. Leaving the rhetoric about fundamentalism, from both, aside, I’m more inclined to agree with the latter. I’ve found TDD to be a practice which does, as Uncle Bob says, help me: &lt;ol&gt;&lt;li&gt;Spend less time debugging &lt;/li&gt;
&lt;li&gt;Document the system at the lowest level in an “accurate, precise, and unambiguous” way. &lt;/li&gt;
&lt;li&gt;Forces me to write higher quality, decoupled code. &lt;/li&gt;
&lt;/ol&gt;I’ve even, occasionally, gotten enough confidence from my unit tests that I do deploy without fear based on passing tests and do feel the confidence to refactor that Uncle Bob describes.&lt;br /&gt;
&lt;br /&gt;
But Uncle Bob left out one, perhaps glaringly obvious and important, benefit that TDD provides that other testing strategies don’t. I suspect this because both DHH and Uncle Bob agree on the need for tests.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;TDD, because it insists on writing the tests first, ensures that the tests are written at all.&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
My fear, based on my experience with other developers, is that despite DHH’s careful phrasing, most developers will only hear “TDD is dead.” To many, if not most, developers the question isn’t, “Do we write the tests first or last?” but “Do we write tests at all?” In my experience, TDD was the practice that gave me enough of a reason to write the tests.&lt;br /&gt;
&lt;br /&gt;
Though I would agree that tests were necessary and led to higher quality code, I always found writing tests afterwards something that I would rarely, if ever, do. Why? because the code “obviously worked.” Never mind the fact that it actually probably didn’t, or at least, didn’t always work. Even now, say when I’ve written some experimental code to try and figure out how something works, I find that when I go to write the production code I discover things about the experimental code that were broken when I write the tests (first) for the production version.&lt;br /&gt;
&lt;br /&gt;
Even within the last week I’ve had conversations with developers who insist that TDD slows you down and “customers don’t pay us to write tests.” While true in part, these sorts of myths are drive people to omit tests entirely, not test last or test using alternative methods. I fear that they will only be reinforced by DHH’s post.&lt;br /&gt;
&lt;br /&gt;
To borrow a concept, &lt;a href=&quot;http://alistair.cockburn.us/Shu+Ha+Ri&quot; target=&quot;_blank&quot;&gt;Shu Ha Ri&lt;/a&gt;, from &lt;a href=&quot;http://alistair.cockburn.us/&quot; target=&quot;_blank&quot;&gt;Alistair Cockburn&lt;/a&gt;, I feel like the “conversation” between DHH and Uncle Bob is taking place between two people at the &lt;em&gt;Ri&lt;/em&gt;, or fluent stage that will be misinterpreted by the majority of us in the &lt;em&gt;Shu&lt;/em&gt;, or follower, stage. Because the practices at this stage are still being ingrained and can take effort to master, they are easily abandoned when another “expert” weighs in and discredits them. In our sound-bite culture, this is especially pernicious as DHH isn’t advocating the abandonment of testing (which I think many will hear) but an alternative practice of testing.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;My Practice&lt;/h2&gt;&lt;h5&gt;Or How I Make TDD Work for Me&lt;/h5&gt;First and foremost I consider myself to be committed to high quality code. Secondarily, I consider myself to be a pragmatist. When I started doing TDD, I tested everything. I also found myself writing prescriptive, rather than descriptive tests. I can still tend to do this if I’m not careful.&lt;br /&gt;
&lt;br /&gt;
What do I mean by that? I mean that the tests were describing how things got done rather than what was being done. I think this is one of the key pitfalls of poorly done TDD and leads to tests being brittle and hard to maintain (though it&#39;s true about all tests, it&#39;s just that - mostly - those other tests are never written). Since this is one of the common criticisms of TDD, I think it&#39;s important to note that it&#39;s also something that needs to change if you&#39;re going to be successful at TDD. These days I try to write tests that are the least constraining as possible and define behavior, not implementations as much as possible.&lt;br /&gt;
&lt;br /&gt;
I also try to only test meaningful code that &lt;strong&gt;I write&lt;/strong&gt;. &quot;Meaningful&quot; is a tricky concept as sometimes I find myself going back and adding a test that I didn&#39;t think initially was meaningful...until it broke in QA. Logging is one of those things that I don&#39;t often test unless there are specific requirements around it. IOC container configuration is another. YMMV. &quot;Code I write&quot; is much easier. I avoid testing that the framework or language works. So, for example, no testing of C# properties (i.e., getter/setter methods) unless there is complex logic in it.&lt;br /&gt;
&lt;br /&gt;
The other thing that was crippling to me when I first started with TDD, was copy-paste disease or &lt;em&gt;&quot;DRY-rot&quot;&lt;/em&gt;. By that I mean that I often simply copy-pasted test set-up into each test rather than treating my test code as a first-class entity and applying the same craftsmanship principles to it that I did to the production code. It seems obvious in retrospect, but this was &lt;em&gt;test code&lt;/em&gt;, not &lt;em&gt;production code&lt;/em&gt; (or so my thinking went).  Of course, when things changed that led to a cascading chain of test changes. Again, this is one of the key complaints I hear about TDD (and again all tests).&lt;br /&gt;
&lt;br /&gt;
Now I make sure to refactor my tests to keep my code DRY and employ good architectural principles in my test code as well as my code under test. In my mind it&#39;s all production code. Refactoring to DRY code, just like in your code under test, makes changing the code much less painful and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
I&#39;m also frequently confronted with code that hasn&#39;t been written with TDD or whose tests haven&#39;t been maintained. As a pragmatist, I don&#39;t find it valuable to go back and write tests for existing code, especially when I&#39;m first coming to a project and don&#39;t have a complete understanding of how that code is supposed to work.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;Aside: the lack of tests makes it harder to understand such code since there isn&#39;t an &quot;executable specification&quot; that shows me how the code differs from the, typically, out-of-date or non-existent documentation. At best you can get an incomplete oral history from the previous developer, but even they may not be the original author and only have a limited understanding.&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
If I&#39;m implementing a new feature I will write tests around that feature and refactor as necessary to support testability in the feature. In many cases this means introducing either wrappers around hard to test (read: static) implementations or alternative constructors with suitable default implementations which allow me to introduce dependency injection where it wasn&#39;t before.  Less frequently, while changing features, I&#39;ll write enough tests around the feature to help ensure that I&#39;m not breaking anything. This is easier when there are exiting albeit out-of-date tests as at least the architecture supports testability. As a last resort I do manual testing.&lt;br /&gt;
&lt;br /&gt;
Almost invariably, if TDD hasn&#39;t been used, there are no or only minimal developer tests. I don&#39;t count QA scripts as tests though they serve a valuable purpose, they don&#39;t given the developer enough feedback quickly enough to ensure safety during development. This is almost universal in my experience and leads to the fears I&#39;ve detailed above.&lt;br /&gt;
&lt;br /&gt;
The last thing I&#39;ll mention is, as I alluded to before, I don&#39;t typically write unit tests for experiments or spikes. If I do end up using that code as the basis for production code, I try to follow the practice of commenting out the pieces of it and writing the tests as if the code did not exist and then uncommenting the relevant bit of code to pass the test. Invariably, I find that my experimental code was broken in some significant way when I do this so I try to keep it to a minimum.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;The Need for Speed&lt;/h2&gt;I want to say a word about one the common complaints that I hear about TDD: that TDD slows development. I think that this is both true (and good) and false (and still good).  First, yes, writing the tests in addition to writing the code, particularly &lt;em&gt;before&lt;/em&gt; you write the code can add additional effort to the task. If you otherwise don&#39;t write the test at all, by doing TDD you&#39;ve incurred the entire cost of writing the test. If you otherwise write the test after, by doing TDD you&#39;ve incurred any refactoring you&#39;ve done while writing the code.&lt;br /&gt;
&lt;br /&gt;
So, yes, doing TDD can take more time per unit of code under test than either not testing or writing tests after. BUT... that time isn&#39;t necessarily wasted because it also gives you more time and the impetus to think about the code you are going to write before you write it. In my experience, this leads to better code the first time and less re-writing and can actually save time even during initial development, though it typically does increase it somewhat.&lt;br /&gt;
&lt;br /&gt;
Over the long term, I think the idea that TDD takes more time is patently false. There is a body of research into the topic that shows that testing, and specifically TDD, reduces code defects and re-work significantly (&lt;em&gt;cf&lt;/em&gt;, &lt;a href=&quot;http://stackoverflow.com/questions/237000/is-there-hard-evidence-of-the-roi-of-unit-testing&quot; target=&quot;_blank&quot;&gt;Is There Hard Evidence of the ROI of Unit Testing)&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Ancedotally, I&#39;ve also found that on projects where I&#39;ve used TDD and other developers haven&#39;t tested at all, we&#39;ve spent a lot more effort around the parts of the code that haven&#39;t been tested. While I&#39;d like to take credit for my superior development skills, the reality is that I just prevented a lot of the defects that I otherwise would have made using TDD. When I&#39;m not able to write tests, I make those same errors.&lt;br /&gt;
&lt;br /&gt;
On projects where they have unit tests, I&#39;ve found that when I come in later, I&#39;m much more quickly able to get up to speed and I&#39;m able to develop with more confidence, increasing my productivity, when I have the safety of a unit test suite. Again, in my experience, if you don&#39;t do TDD, you probably also don&#39;t do testing, period.  At the very least, if you wait and write the tests afterwards, you&#39;re still incurring the costs of finding and fixing defects while the code is under development that TDD could have saved you.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Always a Newb&lt;/h2&gt;Finally, while I feel like I&#39;ve learned a lot about testing, in general, and TDD, in particular, over the years by no means do I consider myself as knowing everything. I&#39;m still discovering how to make it work better. I don&#39;t pretend that there aren&#39;t alternative ways that might work as well. Based on my experience, it&#39;s the best thing that I&#39;ve found and I heartily recommend it to anyone who asks. I will happily abandon TDD for any practice that works better. So far I haven&#39;t found one.&lt;br /&gt;
&lt;br /&gt;
I will say, though, that I know enough to be able to safely say that if you&#39;re not doing tests, unit or otherwise, don&#39;t bother weighing in on whether TDD or some other means of test is better...just start testing. If you are testing but haven&#39;t tried TDD, give it a chance. Study the pitfalls (maybe start with &lt;a href=&quot;https://www.youtube.com/watch?v=HNjlJpuA5kQ&quot; target=&quot;_blank&quot;&gt;TDD, Where Did It All Go Wrong&lt;/a&gt; (&lt;a href=&quot;http://codebetter.com/iancooper/&quot; target=&quot;_blank&quot;&gt;Ian Cooper&lt;/a&gt;) and avoid them but don&#39;t blindly dismiss it based on someone else&#39;s experience because there are plenty of us that have a different, markedly better one.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;Edited to correct misspellings and grammar. Now, if I could only find a way of doing TDD on my blog posts.&lt;/em&gt;</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/8233520228950038558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/04/tdd-and-me.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/8233520228950038558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/8233520228950038558'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/04/tdd-and-me.html' title='TDD and Me'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-6989157247033484675</id><published>2014-03-01T12:07:00.000-06:00</published><updated>2014-03-13T08:41:49.429-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="extensions"/><category scheme="http://www.blogger.com/atom/ns#" term="IEnumerable"/><title type='text'>Runtime-typed Generic Collection Extensions</title><content type='html'>Another post inspired by a Stack Overflow &lt;a href=&quot;http://stackoverflow.com/q/22116057/12950&quot; target=&quot;_blank&quot;&gt;question&lt;/a&gt; (see my &lt;a href=&quot;http://stackoverflow.com/a/22116444/12950&quot; target=&quot;_blank&quot;&gt;answer&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
The specific situation encountered by the asker of the question was prompted by a situation in which the asker knew the specific type that was being returned, but only at runtime. The asker wanted to be able to invoke a method delegate that accepted a &lt;em&gt;IEnumerable&amp;lt;Foo&amp;gt;&lt;/em&gt; or &lt;em&gt;IEnumerable&amp;lt;Bar&amp;gt;&lt;/em&gt; that was, presumably, passed as an argument along with the type, &lt;em&gt;Foo&lt;/em&gt; or &lt;em&gt;Bar&lt;/em&gt;, to a framework method that is unaware of the specific type at compile type. The problem is that when the ToList() method is used, it was returning &lt;em&gt;List&amp;lt;object&amp;gt;&lt;/em&gt; instead of &lt;em&gt;List&amp;lt;Foo&amp;gt;&lt;/em&gt; or &lt;em&gt;List&amp;lt;Bar&amp;gt;&lt;/em&gt; as required as required by the delegate that the asker was attempting to invoke. This resulted in an &lt;em&gt;ArgumentException&lt;/em&gt; for the delegate&#39;s &lt;em&gt;Invoke&lt;/em&gt; method as the underlying type was not convertible.&lt;br /&gt;
&lt;br /&gt;
While I suspect that there is probably a better way to create the framework there wasn’t enough information in the question for me to comment on that. Instead I decided to try and construct some extension methods that would produce a collection of the specific type that could be used by the delegate using ideas from the &lt;a href=&quot;http://stackoverflow.com/a/22116342/12950&quot; target=&quot;_blank&quot;&gt;accepted answer&lt;/a&gt; and an &lt;a href=&quot;http://stackoverflow.com/questions/12848673/type-casting-a-runtime-alternative-to-castt/12848842#12848842&quot; target=&quot;_blank&quot;&gt;answer on a similar question&lt;/a&gt; by the indubitable &lt;a href=&quot;http://stackoverflow.com/users/22656/jon-skeet&quot; target=&quot;_blank&quot;&gt;Jon Skeet&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
To provide a test case for the solution I mocked up some classes similar to those in the question. First, there is a &lt;em&gt;Dog&lt;/em&gt;, which knows how to &lt;em&gt;Bark()&lt;/em&gt;, and a &lt;em&gt;Bird&lt;/em&gt;, which knows how to &lt;em&gt;Sing()&lt;/em&gt;.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; Dog
{
    &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; _id;

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; Dog(&lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; id)
    {
        _id = id;
    }

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Bark()
    {
        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;.Format(&lt;span class=&quot;str&quot;&gt;&quot;Woof...{0}&quot;&lt;/span&gt;, _id);
    }
}

&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; Bird
{
    &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; _id;

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; Bird(&lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; id)
    {
        _id = id;
    }

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Sing()
    {
        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;.Format(&lt;span class=&quot;str&quot;&gt;&quot;Squawk...{0}&quot;&lt;/span&gt;, _id);
    }
}&lt;/pre&gt;Then we have a &lt;em&gt;Framework&lt;/em&gt; class that does a query that returns a collection of &lt;em&gt;IEntry&lt;/em&gt; objects, each being an &lt;em&gt;Entry&lt;/em&gt; object with a &lt;em&gt;Data&lt;/em&gt; property that is either a &lt;em&gt;Dog&lt;/em&gt; or a &lt;em&gt;Bird&lt;/em&gt;.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; Framework
{
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; IEnumerable&amp;lt;IEntry&amp;gt; QueryOfAllType(Type type)
    {
        var range = Enumerable.Range(0, 10);

        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (type.IsAssignableFrom(&lt;span class=&quot;kwrd&quot;&gt;typeof&lt;/span&gt;(Bird)))
        {
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; range.Select(i =&amp;gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Entry
                        {
                            Data = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Bird(i)
                        })
                        .ToList();
        }

        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; range.Select(i =&amp;gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Entry
                    {
                        Data = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Dog(i)
                    })
                    .ToList();
    }
}

&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;interface&lt;/span&gt; IEntry
{
    &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; Data { get; }
}

&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; Entry : IEntry
{
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; Data { get; set; }
} &lt;/pre&gt;Lastly, we have our program which will query the &lt;i&gt;Framework&lt;/i&gt; for &lt;i&gt;IEntry&lt;/i&gt; objects of the proper type, select the &lt;i&gt;Data&lt;/i&gt; property, and use the new extensions to convert the collection to a collection of the proper type to be used by a delegate to perform the appropriate action for that object. &lt;b&gt;Note:&lt;/b&gt; the code below has been updated from the previous version to more accurately replicate the original problem - that is, that the type information can&#39;t be inferred from the delegate or the invoking method.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; Program
{
    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Main(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;[] args)
    {
        DoThatThing(&lt;span class=&quot;kwrd&quot;&gt;typeof&lt;/span&gt;(Bird) , Vocalize);
        DoThatThing(&lt;span class=&quot;kwrd&quot;&gt;typeof&lt;/span&gt;(Dog), Vocalize);
    }

    &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; DoThatThing(Type type, Action&amp;lt;IEnumerable&amp;gt; thingToDo)
    {
        var framework = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Framework();

        var result = framework.QueryOfAllType(type)
                              .Select(e =&amp;gt; e.Data)
                              .ToListOfType(type);

        thingToDo.DynamicInvoke(&lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; [] { result });

    }

    &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Vocalize(IEnumerable animals)
    {
        &lt;span class=&quot;kwrd&quot;&gt;foreach&lt;/span&gt; (var animal &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; animals)
        {
            &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (animal &lt;span class=&quot;kwrd&quot;&gt;is&lt;/span&gt; Dog)
            {
               Console.WriteLine(((Dog)animal).Bark());
            }
            &lt;span class=&quot;kwrd&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (animal &lt;span class=&quot;kwrd&quot;&gt;is&lt;/span&gt; Bird)
            {
                Console.WriteLine(((Bird)animal).Sing());
            }
        }
    }
}&lt;/pre&gt;Below is my solution, using reflection to cast the returned collection to the appropriate type and convert the &lt;i&gt;IEnumerable&lt;/i&gt; to a list, retaining the behavior that the actual collection rather than an iterator is produced.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; EnumerableExtensions
{
    &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;readonly&lt;/span&gt; Type _enumerableType = &lt;span class=&quot;kwrd&quot;&gt;typeof&lt;/span&gt;(Enumerable);

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; IEnumerable CastAsType(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; IEnumerable source, Type targetType)
    {
        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (source == &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)
        {
            &lt;span class=&quot;kwrd&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; ArgumentNullException(&lt;span class=&quot;str&quot;&gt;&quot;source&quot;&lt;/span&gt;);
        }

        var castMethod = _enumerableType.GetMethod(&lt;span class=&quot;str&quot;&gt;&quot;Cast&quot;&lt;/span&gt;).MakeGenericMethod(targetType);

        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; (IEnumerable)castMethod.Invoke(&lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;, &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt;[] { source });
    } 

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; IList ToListOfType(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; IEnumerable source, Type targetType)
    {
        var enumerable = CastAsType(source, targetType);

        var listMethod = _enumerableType.GetMethod(&lt;span class=&quot;str&quot;&gt;&quot;ToList&quot;&lt;/span&gt;).MakeGenericMethod(targetType);

        &lt;span class=&quot;kwrd&quot;&gt;try&lt;/span&gt;
        {
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; (IList)listMethod.Invoke(&lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;, &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt;[] { enumerable });
        }
        &lt;span class=&quot;kwrd&quot;&gt;catch&lt;/span&gt; (TargetInvocationException e)
        {
            ExceptionDispatchInfo.Capture(e.InnerException).Throw();
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;; &lt;span class=&quot;rem&quot;&gt;// to satisfy the compiler, never reached&lt;/span&gt;
        }
    } 
}&lt;/pre&gt;This is what I do for fun on Saturdays. The extension code and tests are available on &lt;a href=&quot;https://github.com/tvanfosson/EnumerableExtensions&quot; target=&quot;_blank&quot;&gt;GitHub&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/6989157247033484675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/03/runtime-typed-generic-collection.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/6989157247033484675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/6989157247033484675'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/03/runtime-typed-generic-collection.html' title='Runtime-typed Generic Collection Extensions'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-5400314011631304799</id><published>2014-02-26T08:00:00.000-06:00</published><updated>2014-02-26T19:58:50.616-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="data modeling"/><category scheme="http://www.blogger.com/atom/ns#" term="WebAPI"/><title type='text'>These Aren’t The API Models You’re Looking For</title><content type='html'>I recently answered a &lt;a href=&quot;http://stackoverflow.com/q/21969656/12950&quot; target=&quot;_blank&quot;&gt;question&lt;/a&gt; on Stack Overflow that started me thinking about the differences between domain models and the models you expose through your Web API. While the question was only tangentially related, I thought it would be helpful to think through why I believe that domain models shouldn’t be exposed directly through your API.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-cIsR17r06OE2oUXKnje0DdlODlbBiCDrTjjrzRixV6ITmvvVowztaxuuoC_aALwjR6WX8q5jtOszhGd1lI5InuPrNP76ydzANmRaKs8b1BGBx0e1DQl-FLvtCsI7QPLQS2E3fY9Oil0/s1600/droids-youre-looking-for.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-cIsR17r06OE2oUXKnje0DdlODlbBiCDrTjjrzRixV6ITmvvVowztaxuuoC_aALwjR6WX8q5jtOszhGd1lI5InuPrNP76ydzANmRaKs8b1BGBx0e1DQl-FLvtCsI7QPLQS2E3fY9Oil0/s320/droids-youre-looking-for.jpg&quot; /&gt;&lt;/a&gt;I’ve long argued for model-per-view in MVC and I’ve carried that thinking over to &lt;a href=&quot;http://www.asp.net/web-api&quot; target=&quot;_blank&quot;&gt;WebAPI&lt;/a&gt; as well. In an MVC context, I think that separation of concerns is the strongest argument in favor of using separate view models. Views have specific data needs for display that don’t belong in your domain models. For example, they may contain auxiliary information containing localization or paging. Your views may not need or you may not desire your view models (which can also used as the arguments for POST actions) to contain all domain properties – for example, whether a user is in a role. Or you may expose this as part of the model but validate it in a completely different way, leading to differing validation requirements. Lastly, your views may flatten multiple models into a single, composite model, omitting unimportant details from that particular view’s point of view.&lt;br /&gt;
&lt;br /&gt;
Many or most of these also apply to API models, even though they are or seem to be strictly about the data. While I don&#39;t claim the following to be an exhaustive list, here the reasons I think that you should use separate models for your API and map between your domain and your API models rather than directly expose your domain models.&lt;br /&gt;
&lt;h4&gt;
Hiding Implementation Details&lt;/h4&gt;
There are two reasons why you might want to hide the implementation details of your model. As in MVC, there are likely some record-keeping attributes on your domain models that are not necessary for the proper operation of the API. For example, you may track who created the item and when, who updated it and when - in a HIPPA world you may even track who viewed it, when, and, perhaps, for what purpose. You may also have actual domain information that needs to remain private even if some of the information is exposed; or it may only conditionally be available based on the API consumer&#39;s privileges. This, in itself, is probably enough of a reason to separate your API models from your domain models. Doing this allows you to keep your domain model simpler and cleaner, more appropriate to the data rather than the usage of the data. The alternative would, perhaps, be a multiplication of domain models, representing purpose-specific views and an accompanying complication of your API (or additional APIs) to support those models.&lt;br /&gt;
&lt;h4&gt;
Transforming Implementation Details&lt;/h4&gt;
Similarly, there are aspects of your model to represent relationships in the data that may be irrelevant to the API consumer. You may model a relationship as many-to-many in your domain model. For example, a product may have many accessories while an accessory may be available for more than one product. From a catalog management perspective this makes perfect sense, but for an API that allows an external consumer to access your catalog you may only want to expose it as a one-to-many relationship. &lt;strong&gt;This&lt;/strong&gt; product has &lt;strong&gt;these&lt;/strong&gt; accessories and not expose that the accessories belong to more than one product. You may not even want to model the reverse relationship from accessory to product in the API at all. It might simply be immaterial.&lt;br /&gt;
&lt;br /&gt;
Also you may want to provide localization for product attributes so that your API can be language aware. While your domain model must account for the relationships to alternative text for attributes, you&#39;re likely to perform substitution for those attributes appropriate to the language requested rather than provide all translations, forcing the consumer to pick the correct one for their purpose.&lt;br /&gt;
&lt;h4&gt;
Navigation&lt;/h4&gt;
Navigation in your domain model is established through foreign key relationships in the database, which are translated to object references and collections of object references in your object model. Navigation in APIs is represented by URLs. &quot;RESTful&quot;, &quot;REST-like&quot;, &quot;Hypermedia&quot; - that&#39;s a discussion for a different post - but modern thinking is that your API on the web should leverage web protocols (the verbs and request patterns). This can be a challenge in designing your API as you trade off between model purity and efficiency. &lt;br /&gt;
&lt;br /&gt;
In your object model the cost of navigation is very low (an object reference) but on the web it is exponentially higher - a full web request. The thing that&#39;s clear, though, unless your data set is very small, is that you will have to make compromises to keep your requests from ballooning in size. While you may be able to keep your entire product catalog in memory, it&#39;s not likely that you&#39;re going to want to serialize all of it and deliver it in a single web request. Instead, you&#39;re going to break your API up into multiple methods, each perhaps corresponding to a aggregate root. You may choose to expose navigation between related elements via explicit navigation properties or simply ids that the client uses in constucting the appropriate URLs to request more information.&lt;br /&gt;
&lt;br /&gt;
If you embrace web protocols in your API, you&#39;ll need to account for the differences in navigation properties between your object model and your API.&lt;br /&gt;
&lt;h4&gt;
Versioning&lt;/h4&gt;
Another strong argument in favor of using separate view models is versioning. Because APIs represent a &quot;public&quot; product, tying disparate systems together, it&#39;s rarely possible to simply discard an older API when the underlying domain model is modified. In response API designers need to account for this by introducing some sort of versioning into their API design. If you directly expose your domain models, this could also mean that you would need to introduce versioning into your domain model to support older versions of an API. Decoupling your domain models from your API through the use of purpose-specific API models insulates your domain model from this need. While you may need to main multiple versions of your API models to support multiple versions of your API, your domain model can evolve to support new features without compromise for the sake of the API.&lt;br /&gt;
&lt;h4&gt;
Summary&lt;/h4&gt;
In short, you should use separate API models. Yes, it might seem simpler to directly use your domain models and there are a lot of examples that take this expedient.  In the long run and with a more complex API than typically used for tutorials, separate API models are going to serve you well.</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/5400314011631304799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/02/these-arent-api-models-youre-looking-for.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/5400314011631304799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/5400314011631304799'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/02/these-arent-api-models-youre-looking-for.html' title='These Aren’t The API Models You’re Looking For'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-cIsR17r06OE2oUXKnje0DdlODlbBiCDrTjjrzRixV6ITmvvVowztaxuuoC_aALwjR6WX8q5jtOszhGd1lI5InuPrNP76ydzANmRaKs8b1BGBx0e1DQl-FLvtCsI7QPLQS2E3fY9Oil0/s72-c/droids-youre-looking-for.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-7979743281226972576</id><published>2014-02-22T12:44:00.000-06:00</published><updated>2014-02-22T12:44:17.222-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="anonymous type"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="JsonResult"/><category scheme="http://www.blogger.com/atom/ns#" term="testing"/><title type='text'>Unit testing JsonResult with Nested Anonymous Types</title><content type='html'>Recently I had a need to test some controller actions that returned nested anonymous types. Since the &lt;em&gt;Data&lt;/em&gt; property on the &lt;em&gt;JsonResult&lt;/em&gt; is of type &lt;em&gt;object&lt;/em&gt; this can involve jumping through some hoops with reflection to get access to the properties in the anonymous types.&amp;nbsp; My first attempt was to simply serialize the object, then deserialize it to an anonymous type. This worked, but I found that my nested types were &lt;em&gt;JObject&lt;/em&gt;s and I needed to use cast and convert these to the actual type.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; TestContext
{
    &lt;span class=&quot;rem&quot;&gt;// remainder omitted&lt;/span&gt;
    
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; dynamic ToDynamicObject(&lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; obj, &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; anonymousTemplate)
    {
        var serialized = JsonConvert.SerializeObject(obj);
        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; JsonConvert.DeserializeAnonymousType(serialized, anonymousTemplate);
    }
}&lt;/pre&gt;
Used as&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;var model = _c.ToDynamicObject(result.Data, &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; { success = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;, data = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; SubModel() });

var subModel = ((JObject)model.data).ToObject&amp;lt;SubModel&amp;gt;();&lt;/pre&gt;
I found one solution at &lt;a href=&quot;http://blog.m0sa.net/2011/02/mvc-unit-testing-jsonresult-actions.html&quot; target=&quot;_blank&quot;&gt;http://blog.m0sa.net/2011/02/mvc-unit-testing-jsonresult-actions.html&lt;/a&gt; which seemed to improve upon this by using a wrapper class that implements &lt;em&gt;DynamicObject&lt;/em&gt;. This got me very close to what I wanted except, again, the nested anonymous objects themselves had to be wrapped individually. Here using my initial implementation of an extension method that used it.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;var model = result.Data.AsDynamic();

var cardModel = ((&lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt;)model.data).AsDynamic() &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; SubModel;&lt;/pre&gt;
To fix this I added a bit of code to the wrapper class so that the result of &lt;em&gt;TryGetMember&lt;/em&gt; was an anonymous type, it created and returned a &lt;em&gt;DynamicObject&lt;/em&gt; wrapper around it. To test if the type was anonymous I used the code found at &lt;a href=&quot;http://www.liensberger.it/web/blog/?p=191&quot; title=&quot;http://www.liensberger.it/web/blog/?p=191&quot;&gt;http://www.liensberger.it/web/blog/?p=191&lt;/a&gt; (referenced from this Stack Overflow question, &lt;a href=&quot;http://stackoverflow.com/questions/2483023/how-to-test-if-a-type-is-anonymous&quot; title=&quot;http://stackoverflow.com/questions/2483023/how-to-test-if-a-type-is-anonymous&quot;&gt;http://stackoverflow.com/questions/2483023/how-to-test-if-a-type-is-anonymous&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
Here’s the final implementation as extensions to &lt;em&gt;object&lt;/em&gt;.&amp;nbsp; Note: these are internal to my test project so the restriction to &lt;em&gt;object&lt;/em&gt; doesn’t bother me too much. &lt;em&gt;JsonResult.Data&lt;/em&gt; has that type and that was the problem I was trying to solve.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; ObjectExtensions
{
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; DynamicWrapper : DynamicObject
    {
        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;readonly&lt;/span&gt; Type _subjectType;
        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; _subject;

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; dynamic Create(&lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; subject)
        {
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; DynamicWrapper(subject);
        }

        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; DynamicWrapper(&lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; subject)
        {
            _subject = subject;
            _subjectType = subject.GetType();
        }

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; TryGetMember(GetMemberBinder binder, &lt;span class=&quot;kwrd&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; result)
        {
            &lt;span class=&quot;kwrd&quot;&gt;try&lt;/span&gt;
            {
                var propertyInfo = _subjectType.GetProperty(binder.Name);

                var getter = propertyInfo.GetGetMethod();

                result = getter.Invoke(_subject, &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;);

                &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (result.IsAnonymous())
                {
                    result = Create(result);
                }
                &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
            }
            &lt;span class=&quot;kwrd&quot;&gt;catch&lt;/span&gt;
            {
                result = &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;;
                &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;;
            }
        }
    }

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; IsAnonymous(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; obj)
    {
        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (obj == &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)
        {
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;;
        }

        var type = obj.GetType();

        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; Attribute.IsDefined(type, &lt;span class=&quot;kwrd&quot;&gt;typeof&lt;/span&gt;(CompilerGeneratedAttribute), &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;)
                  &amp;amp;&amp;amp; type.IsGenericType &amp;amp;&amp;amp; type.Name.Contains(&lt;span class=&quot;str&quot;&gt;&quot;AnonymousType&quot;&lt;/span&gt;)
                  &amp;amp;&amp;amp; (type.Name.StartsWith(&lt;span class=&quot;str&quot;&gt;&quot;&amp;lt;&amp;gt;&quot;&lt;/span&gt;) || type.Name.StartsWith(&lt;span class=&quot;str&quot;&gt;&quot;VB$&quot;&lt;/span&gt;))
                  &amp;amp;&amp;amp; (type.Attributes &amp;amp; TypeAttributes.NotPublic) == TypeAttributes.NotPublic;
    }

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; dynamic AsDynamic(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; obj)
    {
        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; DynamicWrapper.Create(obj);
    }
}&lt;/pre&gt;
And the above code sample now becomes much cleaner and I am much happier:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;var model = result.Data.AsDynamic();

var subModel = model.data &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; SubModel;&lt;/pre&gt;
</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/7979743281226972576/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/02/unit-testing-jsonresult-with-nested.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/7979743281226972576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/7979743281226972576'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/02/unit-testing-jsonresult-with-nested.html' title='Unit testing JsonResult with Nested Anonymous Types'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-16295784046127458</id><published>2014-02-12T21:12:00.002-06:00</published><updated>2014-10-07T14:58:38.630-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Dapper"/><category scheme="http://www.blogger.com/atom/ns#" term="testing"/><title type='text'>Putting It All Together: TDD for Dapper Repositories</title><content type='html'>In the last several posts I&#39;ve set up the infrastructure for doing Test Driving Development for Dapper with lightweight integration tests. You might want to review these if you haven&#39;t already looked at them.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaiW5kKrGK8NEY2971Wm54_LX8PfjBTw7uM3qC3CkHftA7GZ1SWzWkZl75GUBNsqrrwt3bNxEaRDW3O_vRKJ-H3AzmEr3u0O6hMJVpyS4CYtjZeSXQsTUFbKyxUfHTnaySMy8XSrGzOGU/s1600/dapper-gentleman.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaiW5kKrGK8NEY2971Wm54_LX8PfjBTw7uM3qC3CkHftA7GZ1SWzWkZl75GUBNsqrrwt3bNxEaRDW3O_vRKJ-H3AzmEr3u0O6hMJVpyS4CYtjZeSXQsTUFbKyxUfHTnaySMy8XSrGzOGU/s320/dapper-gentleman.png&quot; /&gt;&lt;/a&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;&lt;a href=&quot;http://farm-fresh-code.blogspot.com/2014/02/lightweight-integration-testing-with.html&quot;&gt;Lightweight Integration Testing with Dapper&lt;/a&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;&lt;a href=&quot;http://farm-fresh-code.blogspot.com/2014/02/solving-challenges-of-dapper_9.html&quot;&gt;Solving the Challenges of Dapper Integration Testing: Part 1&lt;/a&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;&lt;a href=&quot;http://farm-fresh-code.blogspot.com/2014/02/solving-challenges-of-dapper.htmll&quot;&gt;Solving the Challenges of Dapper Integration Testing: Part 2&lt;/a&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;&lt;a href=&quot;http://farm-fresh-code.blogspot.com/2014/02/solving-challenges-of-dapper_11.html&quot;&gt;Solving the Challenges of Dapper Integration Testing: Part 3&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
I&#39;m going to keep it relatively simple for this example. Essentially my repositories are just going to implement CRUD operations for each aggregate root. There will be &lt;em&gt;Create&lt;/em&gt;, &lt;em&gt;Get&lt;/em&gt; and &lt;em&gt;GetAll&lt;/em&gt; (Read), &lt;em&gt;Update&lt;/em&gt;, and &lt;em&gt;Delete&lt;/em&gt; methods. I’m also going to make the choice to have most exceptions bubble up. This might not be the best choice but it will keep the example simple. In fact, you might want to catch most exceptions and transform them into application-level exceptions which you’d handle at higher levels. Testing exceptional behavior is more difficult to set up in integration tests and we can more easily test exceptions with true unit tests in the classes that use our repositories.&lt;br /&gt;
&lt;br /&gt;
Because these are actually integration tests we run into a chicken and egg issue. Unless we write some other (duplicate) code, we can&#39;t test &lt;em&gt;Get()&lt;/em&gt; without &lt;em&gt;Create()&lt;/em&gt; or &lt;em&gt;Create()&lt;/em&gt; without &lt;em&gt;Get(&lt;/em&gt;) in a self-contained test method.&lt;br /&gt;
My solution is pragmatic, start with &lt;em&gt;Get()&lt;/em&gt;. The logic is relatively simple and easier to convince yourself of it&#39;s correctness. You could write some code using a data reader to read and verify that something is created but you&#39;d still have to convince yourself that code is correct. Since we&#39;re not so much testing Dapper - it already has tests - as we are our SQL, I prefer to start off with Get() and not write the extra code. As they say, &quot;your mileage may vary,&quot; you might want to start with something else.&lt;br /&gt;
&lt;br /&gt;
Note you won&#39;t be able to create tests for &lt;em&gt;Get()&lt;/em&gt; until you&#39;ve done &lt;em&gt;Create()&lt;/em&gt;, but once you&#39;ve created your &lt;em&gt;Get()&lt;/em&gt; implementation and convinced yourself of its correctness, you can move onto Create() and use TDD to create that code. After you can create and retrieve an object, you&#39;re ready for &lt;em&gt;GetAll()&lt;/em&gt;, &lt;em&gt;Delete()&lt;/em&gt;, &lt;em&gt;Update()&lt;/em&gt;, and any specialized methods. Do go back and create tests for &lt;em&gt;Get()&lt;/em&gt;. These are after all, integration tests, we can write those after the fact. As we&#39;ll see that will come in handy later when we extend our &lt;em&gt;Get()&lt;/em&gt; implementation to get some related data from another table.&lt;br /&gt;
&lt;br /&gt;
We’re going to create two separate repositories, one for &lt;em&gt;Users&lt;/em&gt; and one for &lt;em&gt;Posts&lt;/em&gt;. Let&#39;s start with the &lt;em&gt;DapperUserRepository&lt;/em&gt; first. All of the code referenced below can be found, though in it&#39;s final form, at &lt;a href=&quot;https://github.com/tvanfosson/dapper-integration-testing&quot; target=&quot;_blank&quot; title=&quot;GitHub source link&quot;&gt;https://github.com/tvanfosson/dapper-integration-testing&lt;/a&gt;&lt;br /&gt;
&lt;h4&gt;DapperUserRepository&lt;/h4&gt;First, we&#39;ll solve our &quot;chicken and egg&quot; problem by implementing &lt;em&gt;Get()&lt;/em&gt;.   &lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; User Get(&lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; id)
{
    &lt;span class=&quot;kwrd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; sql = &lt;span class=&quot;str&quot;&gt;&quot;SELECT * FROM [Users] WHERE [Id] = @userId&quot;&lt;/span&gt;;

    var user = Fetch(c =&amp;gt; c.Query&amp;lt;User&amp;gt;(sql, &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; { userId = id }).SingleOrDefault());

    &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; user;
}&lt;/pre&gt;Now, if you’re paying attention, you should be saying “Wait a minute – that’s too much code there. You’re cheating.” Yes, I am.I’m showing you the results after some refactoring – refactoring done in another project.In another project I found it helpful to develop a base repository pattern. This base implementation provides some convenient methods for performing the Dapper &lt;em&gt;Query&lt;/em&gt; and &lt;em&gt;Execute&lt;/em&gt; operations. Below is the base class implementation for the repositories we&#39;ll create. Since I&#39;ve tested this pattern in other projects, I feel comfortable starting with it as the basis for my new repositories.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; DapperRepositoryBase
{
    &lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;readonly&lt;/span&gt; IConnectionFactory _connectionFactory;
    &lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; _connectionStringName;

    &lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; DapperRepositoryBase(IConnectionFactory connectionFactory, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; connectionStringName)
    {
        _connectionFactory = connectionFactory;
        _connectionStringName = connectionStringName;
    }

    &lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; DbConnection OpenConnection()
    {
        var connection = _connectionFactory.Create(_connectionStringName);
        connection.Open();
        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; connection;
    }

    &lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; T Fetch&amp;lt;T&amp;gt;(Func&amp;lt;DbConnection, T&amp;gt; func)
    {
        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (func == &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)
        {
            &lt;span class=&quot;kwrd&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; ArgumentNullException(&lt;span class=&quot;str&quot;&gt;&quot;func&quot;&lt;/span&gt;);
        }

        &lt;span class=&quot;kwrd&quot;&gt;using&lt;/span&gt; (var connection = OpenConnection())
        {
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; func(connection);
        }
    }

    &lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; Execute(Func&amp;lt;DbConnection, &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt;&amp;gt; func)
    {
        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (func == &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)
        {
            &lt;span class=&quot;kwrd&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; ArgumentNullException(&lt;span class=&quot;str&quot;&gt;&quot;func&quot;&lt;/span&gt;);
        }

        &lt;span class=&quot;kwrd&quot;&gt;using&lt;/span&gt; (var connection = OpenConnection())
        {
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; func(connection);
        }
    }

    &lt;span class=&quot;rem&quot;&gt;// remainder of class omitted&lt;/span&gt;
}&lt;/pre&gt;If you want to start without the base class implementation, your &lt;em&gt;Get()&lt;/em&gt; implementation might look a little bigger, maybe like the following. For the rest of the examples, we&#39;ll use my base class and I hope it will be obvious where the refactorings came from.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; User Get2(&lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; id)
{
    &lt;span class=&quot;kwrd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; sql = &lt;span class=&quot;str&quot;&gt;&quot;SELECT * FROM [Users] WHERE [Id] = @userId&quot;&lt;/span&gt;;

    &lt;span class=&quot;kwrd&quot;&gt;using&lt;/span&gt; (var connection = _connectionFactory.Create(_connectionStringName))
    {
        connection.Open();

        var user = connection.Query&amp;lt;User&amp;gt;(sql, &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; { userId = id }).SingleOrDefault();

        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; user;
    }
}&lt;/pre&gt;Now that we have (as we&#39;ve convinced ourselves) a working &lt;em&gt;Get()&lt;/em&gt; method, we can now turn to developing &lt;em&gt;Create&lt;/em&gt;. First, we stub it in and have it throw a &lt;em&gt;NotImplementedException&lt;/em&gt;. &lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; DapperUserRepository : DapperRepositoryBase, IUserRepository
{
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; DapperUserRepository(IConnectionFactory connectionFactory, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; connectionStringName)
        : &lt;span class=&quot;kwrd&quot;&gt;base&lt;/span&gt;(connectionFactory, connectionStringName)
    {
    }

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Create(User user)
    {
        &lt;span class=&quot;kwrd&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; NotImplementedException();
    }

    &lt;span class=&quot;rem&quot;&gt;// Get omitted&lt;/span&gt;
}&lt;/pre&gt;Then, we&#39;ll create our first test. Typically I&#39;ll start with the success case first. In this case, we&#39;ll test that a &lt;em&gt;User&lt;/em&gt; can be successfully created. We&#39;ll add some helper methods to the test context that allows us to get an instance of the repository and create a user with some pre-filled properties. Note that since we&#39;re using autoincrement ids, our create code will need to fill this value in when performing the insert.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; DapperUserRepositoryTests : TestBase
{
    &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; DapperUserRepositoryTestContext _c;

    [TestMethod]
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; When_a_new_user_is_created_the_data_is_inserted()
    {
        var repository = _c.GetRepository();
        var user = _c.CreateStandardUser();

        repository.Create(user);

        var retrievedUser = repository.Get(user.Id);

        Assert.AreEqual(user.DisplayName, retrievedUser.DisplayName);
        Assert.AreEqual(user.Email, retrievedUser.Email);
        Assert.AreEqual(user.Active, retrievedUser.Active);
    }
    
    &lt;span class=&quot;rem&quot;&gt;// test context omitted&lt;/span&gt;
}&lt;/pre&gt;We run the test and it fails, as expected. Now let&#39;s provide the least code necessary, in an integration test context, to satisfy the test, that is, insert the record into the database so that when it&#39;s retrieved the stored values are matched by the retrieved values. We need to insert the &lt;em&gt;DisplayName&lt;/em&gt;, &lt;em&gt;Email&lt;/em&gt;, &lt;em&gt;CreatedDate&lt;/em&gt;, and &lt;em&gt;Active&lt;/em&gt; state.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Create(User user)
{
    &lt;span class=&quot;kwrd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; sql = &lt;span class=&quot;str&quot;&gt;&quot;INSERT INTO [Users] ([DisplayName], [Email], [CreatedDate], [Active]) OUTPUT inserted.[Id] VALUES (@displayName, @email, @createdDate, @active)&quot;&lt;/span&gt;;

    var id = Fetch(c =&amp;gt; c.Query&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt;&amp;gt;(sql, &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt;
    {
        displayName = user.DisplayName,
        email = user.Email,
        createdDate = DateTime.Now,
        active = user.Active
    }).Single());

    user.Id = id;
}&lt;/pre&gt;We run the test now and it passes. Next we might want to test that the created date is also updated when the user is created. This is a bit tricky because we can&#39;t simply compare dates between the CLR and SqlServer; since their resolutions are different we&#39;ll get spurious errors. One way around this is to take a snapshot of the time right before and right after the insert and make sure that the inserted date falls between those ranges within an acceptable bound - for me I only care about it being accurate to the nearest second. We&#39;ll use another helper method to round our times to the nearest second for comparison. Thus our next test is:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;[TestMethod]
&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; When_a_new_user_is_created_the_current_time_is_set_as_the_created_date()
{
    var repository = _c.GetRepository();
    var user = _c.CreateStandardUser();

    var before = _c.RoundToSecond(DateTime.Now);
    repository.Create(user);
    var after = _c.RoundToSecond(DateTime.Now);

    var retrievedUser = repository.Get(user.Id);

    var created = _c.RoundToSecond(retrievedUser.CreatedDate);

    &lt;span class=&quot;rem&quot;&gt;// we only care about the nearest second&lt;/span&gt;
    Assert.IsTrue(before &amp;lt;= created &amp;amp;&amp;amp; created &amp;lt;= after);
}&lt;/pre&gt;Running this test fails because we&#39;re not retrieving the &lt;em&gt;CreatedDate&lt;/em&gt;.  In this case I think it&#39;s easier to set the value on the object instead of storing it, so we&#39;ll implement it as follows.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Create(User user)
{
    var date = DateTime.Now;

    &lt;span class=&quot;kwrd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; sql = &lt;span class=&quot;str&quot;&gt;&quot;INSERT INTO [Users] ([DisplayName], [Email], [CreatedDate], [Active]) OUTPUT inserted.[Id] VALUES (@displayName, @email, @createdDate, @active)&quot;&lt;/span&gt;;

    var id = Fetch(c =&amp;gt; c.Query&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt;&amp;gt;(sql, &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt;
    {
        displayName = user.DisplayName,
        email = user.Email,
        createdDate = date,
        active = user.Active
    }).Single());

    user.Id = id;
    user.CreatedDate = date;
}&lt;/pre&gt;Note that we don&#39;t set any values on the object until the &lt;em&gt;Fetch&lt;/em&gt; has succeeded - we don&#39;t want the object state to be updated if there is an exception. Even though the code (appears) to work that way, we&#39;ll create another test to ensure that.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;[TestMethod]
&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; When_an_exception_is_thrown_the_id_and_date_are_not_updated()
{
    var repository = _c.GetRepository();
    var user = _c.CreateStandardUser();
    var otherUser = _c.CreateStandardUser(1);
    otherUser.DisplayName = user.DisplayName;

    repository.Create(user);

    var expectedId = otherUser.Id = -1;
    var expectedDate = otherUser.CreatedDate = DateTime.MinValue;

    &lt;span class=&quot;kwrd&quot;&gt;try&lt;/span&gt;
    {
        repository.Create(otherUser);
        Assert.Fail(&lt;span class=&quot;str&quot;&gt;&quot;Expected SqlException not thrown.&quot;&lt;/span&gt;);
    }
    &lt;span class=&quot;kwrd&quot;&gt;catch&lt;/span&gt; (SqlException)
    {
        Assert.AreEqual(expectedId, otherUser.Id);
        Assert.AreEqual(expectedDate, otherUser.CreatedDate);
    }
}&lt;/pre&gt;And that test passes, as we hoped. We continue writing tests in this manner, testing small bits of functionality until we believe that our methods perform the way we think they should. While it won&#39;t be possible without developing a parallel implementation for our functions to develop the tests without interdependencies, this gives us a reasonably simple way to build up our code in a Test Driven fashion.&lt;br /&gt;
&lt;br /&gt;
Hopefully this small example, with the code included in the GitHub repository, has shown you how to get started doing TDD with Dapper. I&#39;ve left the code in the repository incomplete so you can experiment with it. In particular, there are some interesting behaviors in the &lt;em&gt;Post&lt;/em&gt; repository. You might want to experiment with getting the posts associated with a specific user, which returns a filtered collection, for example.</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/16295784046127458/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/02/putting-it-all-together-tdd-for-dapper.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/16295784046127458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/16295784046127458'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/02/putting-it-all-together-tdd-for-dapper.html' title='Putting It All Together: TDD for Dapper Repositories'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaiW5kKrGK8NEY2971Wm54_LX8PfjBTw7uM3qC3CkHftA7GZ1SWzWkZl75GUBNsqrrwt3bNxEaRDW3O_vRKJ-H3AzmEr3u0O6hMJVpyS4CYtjZeSXQsTUFbKyxUfHTnaySMy8XSrGzOGU/s72-c/dapper-gentleman.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-7946126290957175480</id><published>2014-02-11T13:04:00.000-06:00</published><updated>2014-02-12T21:13:14.124-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Dapper"/><category scheme="http://www.blogger.com/atom/ns#" term="testing"/><title type='text'>Solving the Challenges of Dapper Integration Testing: Part 3</title><content type='html'>&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaiW5kKrGK8NEY2971Wm54_LX8PfjBTw7uM3qC3CkHftA7GZ1SWzWkZl75GUBNsqrrwt3bNxEaRDW3O_vRKJ-H3AzmEr3u0O6hMJVpyS4CYtjZeSXQsTUFbKyxUfHTnaySMy8XSrGzOGU/s1600/dapper-gentleman.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img alt=&quot;A Dapper Gentleman&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaiW5kKrGK8NEY2971Wm54_LX8PfjBTw7uM3qC3CkHftA7GZ1SWzWkZl75GUBNsqrrwt3bNxEaRDW3O_vRKJ-H3AzmEr3u0O6hMJVpyS4CYtjZeSXQsTUFbKyxUfHTnaySMy8XSrGzOGU/s1600/dapper-gentleman.png&quot; title=&quot;&quot; /&gt;&lt;/a&gt;This is the fourth in a series of posts on lightweight integration testing with Dapper. These lightweight tests will enable us to do Test-Driven Development when creating our Dapper-based repositories. In my previous posts I’ve discussed the goals for our tests and covered three of the four challenges that were introduced. The &lt;a href=&quot;http://farm-fresh-code.blogspot.com/2014/02/lightweight-integration-testing-with.html&quot;&gt;first post&lt;/a&gt; in the series introduced our goals: tests that are automated, fast, simple, independent, self-contained, safe, and require minimal extra tooling to implement. The &lt;a href=&quot;http://farm-fresh-code.blogspot.com/2014/02/solving-challenges-of-dapper_9.html&quot;&gt;second &lt;/a&gt;and &lt;a href=&quot;http://farm-fresh-code.blogspot.com/2014/02/solving-challenges-of-dapper.html&quot;&gt;third &lt;/a&gt;have covered the challenges so far: providing a data connection, isolating the execution of the tests, and cleaning up our test data between tests.&lt;br /&gt;
&lt;br /&gt;
In this post we’ll cover the last remaining challenge: keeping the test database schema in sync with our production database. This code and the code for all previous posts is available at&amp;nbsp;&lt;a href=&quot;https://github.com/tvanfosson/dapper-integration-testing&quot; target=&quot;_blank&quot;&gt;https://github.com/tvanfosson/dapper-integration-testing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Synchronizing the Schema&lt;/h3&gt;&lt;br /&gt;
To keep our database synchronized, and in fact, to provide a way to maintain our database schema we’ll borrow a concept used in Ruby/Rails and Entity Framework, namely database migrations. While we could do this entirely in code, I’m going to leverage the SQL Server Management Studio (SSMS) tooling and maintain the migrations as a collection of SQL scripts and automate their execution in code. This provides a good compromise, in my opinion, between the complexity of creating an entirely code-based migrations infrastructure and the burden of keeping the database schemas in sync manually.&lt;br /&gt;
&lt;br /&gt;
Certainly, though, if there were one area of this solution that I could improve it would be this one. One possible alternative would be to use &lt;a href=&quot;http://msdn.microsoft.com/en-us/data/jj591621.aspx&quot;&gt;Entity Framework migrations&lt;/a&gt; with or without using Entity Framework as the ORM (object-relational mapper). Such a solution would, perhaps, be ideal if you were augmenting your Entity Framework-based application with targeted use of Dapper for specific queries requiring the speed advantage that Dapper provides. Because this series is Dapper focused, however, I’m going to use the solution described above: SQL scripts, executed automatically in our test framework. The solution I described is specific to Microsoft SQL Server and SSMS-generated scripts, but can be adapted as needed for other databases and tooling. If you’re not familiar with the Generate Scripts wizard in SSMS, you can find more information at &lt;a href=&quot;http://technet.microsoft.com/en-us/library/bb895179.aspx&quot;&gt;http://technet.microsoft.com/en-us/library/bb895179.aspx&lt;/a&gt;.&lt;br /&gt;
&lt;h4&gt;Approach&lt;/h4&gt;I will be using a database-first approach. By that I mean that I will use SSMS to create the database tables, indexes, relations, &lt;em&gt;etc&lt;/em&gt;. and then reverse-engineer the scripts that will be used to create and upgrade the production database.&amp;nbsp; These scripts may be edited by hand to ensure that existing data is preserved and migrated as needed as the schema changes. There are three types of scripts that you might want to produce. Two of these will be used in maintaining the database itself, the “up” and “down” scripts. These are used to create/upgrade and back out upgrades, respectively. We’ll make use of the “up” scripts, which I typically name with “Create” or “Add” (as in “add this functionality”) in the script name. The third type of script, the “delete” script will be used solely for our testing purposes. This could be automated in the same manner as our database clean up, but since these scripts are easy enough to generate with the wizard we’ll leave that for a future exercise.&lt;br /&gt;
&lt;h4&gt;Create the Database&lt;/h4&gt;For my example, I’m going to use the tried and true (and trite) blog post. Note: the model is not intended to be realistic, but rather illustrative of the concepts that we’ll use for testing.&lt;br /&gt;
&lt;br /&gt;
We’ll create tables representing &lt;em&gt;Users&lt;/em&gt;, &lt;em&gt;Posts&lt;/em&gt;, and &lt;em&gt;PostDetails&lt;/em&gt;. The table names follow the plural convention and will typically correspond with our models directly. All of our tables will use artificial, auto-increment integer identity columns, named &lt;em&gt;Id&lt;/em&gt;, as their primary keys. A &lt;em&gt;User&lt;/em&gt; will have a &lt;em&gt;DisplayName&lt;/em&gt; (nvarchar), &lt;em&gt;Email&lt;/em&gt; (login id) (nvarchar), a &lt;em&gt;CreatedDate&lt;/em&gt; (datetime), and a bit column, &lt;em&gt;Active&lt;/em&gt;, indicating whether the user is currently an active user or not.&lt;br /&gt;
&lt;br /&gt;
A &lt;em&gt;Post&lt;/em&gt; has an associated &lt;em&gt;OwnerId&lt;/em&gt;, a foreign key to the &lt;em&gt;Id&lt;/em&gt; in the &lt;em&gt;Users&lt;/em&gt; table, a &lt;em&gt;Title&lt;/em&gt; (nvarchar), &lt;em&gt;Slug&lt;/em&gt; (nvarchar), a &lt;em&gt;PostedDate&lt;/em&gt; (datetime), &lt;em&gt;EditedDate&lt;/em&gt; (datetime), and a bit column indicating whether the post is &lt;em&gt;Deleted&lt;/em&gt; or not. Well, set the foreign key (FK) relationship up to cascade on delete. It has an additional non-unique index on the &lt;em&gt;OwnerId&lt;/em&gt; column. I anticipate that our routes would incorporate the Post Id and so an index on the &lt;em&gt;Slug&lt;/em&gt; column isn’t necessary.&lt;br /&gt;
&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: right; margin-left: 1em; text-align: right;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii5koWcIJiBEJooHoM7XBFwf7RvfJrjBCEcGb8lmIFvu8sTKHaf2pj39vyppWHq9lAkK-7TbXkxv4kNWWBmD9zwZvAzwTF7YKjb1LVtDBNIKMCE_QSM2WndvadsM53xhhadbP99tj2V7Q/s1600/Generate+Scripts.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img alt=&quot;Generate scripts dialog&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii5koWcIJiBEJooHoM7XBFwf7RvfJrjBCEcGb8lmIFvu8sTKHaf2pj39vyppWHq9lAkK-7TbXkxv4kNWWBmD9zwZvAzwTF7YKjb1LVtDBNIKMCE_QSM2WndvadsM53xhhadbP99tj2V7Q/s1600/Generate+Scripts.png&quot; height=&quot;291&quot; title=&quot;Generate Create and Delete Scripts&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Generate Create and Delete Scripts&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;Each &lt;em&gt;Post&lt;/em&gt; has a related &lt;em&gt;PostDetail&lt;/em&gt; through the &lt;em&gt;PostId&lt;/em&gt;, foreign key on &lt;em&gt;PostDetails&lt;/em&gt; to &lt;em&gt;Post&lt;/em&gt;. The &lt;em&gt;PostDetail&lt;/em&gt; will consist of a &lt;em&gt;SequenceNumber&lt;/em&gt; (int) and a &lt;em&gt;Text&lt;/em&gt; column containing the actual contents of one part of a &lt;em&gt;Post&lt;/em&gt;. &lt;em&gt;SequenceNumber&lt;/em&gt; will be maintained by our application and will represent separate “pages” in a post. For simplicity we’ll set the &lt;em&gt;Text&lt;/em&gt; column up as nvarchar(MAX). It might contain HTML or MarkDown. The FK relationship will be set up to cascade on delete. We will add a unique index on &lt;em&gt;PostId&lt;/em&gt; and &lt;em&gt;SequenceNumber&lt;/em&gt;, enabling us to use index joins to get the related details for a post quickly.&lt;br /&gt;
&lt;br /&gt;
This will be our simple database. Using &lt;em&gt;Tasks→Generate Scripts&lt;/em&gt; we’ll create &lt;em&gt;000-Create-DapperTesting.sql&lt;/em&gt; and &lt;em&gt;000-Drop-DapperTesting.sql&lt;/em&gt;. These will be stored in a &lt;em&gt;DatabaseScripts&lt;/em&gt; directory in our source code repository. &lt;strong&gt;To ensure success make sure you configure the options to check for existence when generating these scripts under the &lt;em&gt;Advanced&lt;/em&gt; options setting in the wizard.&lt;/strong&gt; You will also want to make sure that all of the necessary objects are included.&lt;br /&gt;
&lt;h4&gt;Automatically Provision the Test Database&lt;/h4&gt;&lt;strong&gt;&lt;em&gt;Add the test database to the solution&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: left; margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3qFSfKoAyKmGkslvCyFfRX_3oDmaDZLi3l6qXB6doClJ0YOwNRD08Gx3Yz1HYDr9eqj0EQ_31rfA5e-od35WkA_atdnApEOiI03GcAeEaEWhRVYlEI4JtbvYtlSInXpc_rdQZebVMNKc/s1600/Create+LocalDB.PNG&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img alt=&quot;Add New Items - Data - Service-based Database Dialog&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3qFSfKoAyKmGkslvCyFfRX_3oDmaDZLi3l6qXB6doClJ0YOwNRD08Gx3Yz1HYDr9eqj0EQ_31rfA5e-od35WkA_atdnApEOiI03GcAeEaEWhRVYlEI4JtbvYtlSInXpc_rdQZebVMNKc/s1600/Create+LocalDB.PNG&quot; height=&quot;221&quot; title=&quot;Add a Service-based Database to the Unit Test Project&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Add a Service-based Database to the Unit Test Project&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;As I noted in previous posts we’ll be using a LocalDB database for our test database. Once we’ve created our unit test project, we’ll add a Service-based Database to our project. Right-click on the test project, and choose &lt;em&gt;Add Item→New&lt;/em&gt;. Select &lt;em&gt;Data&lt;/em&gt;, then choose &lt;em&gt;Service-based Database&lt;/em&gt;. I gave mine the name &lt;em&gt;DapperTestingDB.mdf&lt;/em&gt;. Once you&#39;ve completed this step, you will want to make sure that the log file is also added to the solution using &lt;em&gt;Add→Existing item&lt;/em&gt;, then selecting the LDF file associated with the database. Use the properties dialog to set both the MDF and LDF items as Content items. To be safe, I also set mine up to Copy Always. &lt;b&gt;It&#39;s important that the MDF and LDF files be deployed at the same time since an out-of-date log file will prevent your LocalDB instance from being used.&lt;/b&gt; By copying both new for each build, this avoids that problem, though you could probably get by with Copy If Newer. I changed mine to Copy Always in the process of debugging the log file synchronization issue and simply haven&#39;t changed it back on the theory that you don&#39;t change things that aren&#39;t broken.&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;clear: both;&quot;&gt;&lt;strong&gt;&lt;em&gt;Update the TestContextBase&lt;/em&gt;&lt;/strong&gt;&lt;/div&gt;&lt;br /&gt;
Now that we have our (empty) test database in the solution, we need a way to initialize it. In fact, we want to reinitialize it each run to capture any changes that may have been made. To do this we’ll update our &lt;em&gt;TestContextBase&lt;/em&gt; class that I introduced in my previous posts.&lt;br /&gt;
&lt;br /&gt;
Because we only want the database to be initialized once per test run, not once per test, we’ll create a &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx&quot;&gt;static constructor&lt;/a&gt; that invokes the database initialization code. A static constructor is run once, before “the first instance is created or any static members are referenced.”&amp;nbsp; Because our static constructor is on the base class, this means that it will be executed once for any and all test contexts that derive from it. This constructor is relatively simple. In it we find the “down” and “up” (or “delete” and “create” as they are called internally) scripts, then first execute the delete scripts, then the create scripts.&lt;br /&gt;
&lt;br /&gt;
In this way, we make sure that each test run starts off with a fresh database that is synchronized to the latest schema represented in the scripts. By making sure that we check for object existence before we delete (or create) it, we can be sure that changes to the scripts don’t cause errors due to a new database object being introduced – that object won’t exist yet and so the existence check will fail and the associated delete will not be attempted.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; TestContextBase : IDisposable
{
    &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; ScriptsDirectory = &lt;span class=&quot;str&quot;&gt;@&quot;..\..\..\..\DatabaseScripts\&quot;;
    private readonly static string[] _createScripts = { &quot;&lt;/span&gt;000-Create-DapperTesting.sql&lt;span class=&quot;str&quot;&gt;&quot; };
    private static readonly string[] _deleteScripts = { &quot;&lt;/span&gt;000-Drop-DapperTesting.sql&lt;span class=&quot;str&quot;&gt;&quot; };
    private readonly static string _dbFile = Path.Combine(Environment.CurrentDirectory, &quot;&lt;/span&gt;DapperTestingDB.mdf&lt;span class=&quot;str&quot;&gt;&quot;);
    private static readonly string _connectionString = @&quot;&lt;/span&gt;Data Source=(LocalDB)\v11.0;Initial Catalog=DapperTesting;Integrated Security=True;AttachDbFilename=&quot; + _dbFile;

    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; TestContextBase()
    {
        var deleteScripts = _deleteScripts.Select(s =&amp;gt; Path.Combine(ScriptsDirectory, s)).ToList();
        var createScripts = _createScripts.Select(s =&amp;gt; Path.Combine(ScriptsDirectory, s)).ToList();

        Assert.IsTrue(deleteScripts.All(File.Exists));
        Assert.IsTrue(createScripts.All(File.Exists));

        ExecuteScripts(deleteScripts);
        ExecuteScripts(createScripts);
    }
    
    &lt;span class=&quot;rem&quot;&gt;// remainder of class omitted&lt;/span&gt;
}&lt;/pre&gt;The implementation of &lt;em&gt;ExecuteScripts&lt;/em&gt; for MS-SQL is interesting in that the scripts generated by SSMS cannot be run directly using &lt;em&gt;SqlCommand&lt;/em&gt; due to the inclusion of comments, USE, and the SSMS-special &lt;a href=&quot;http://stackoverflow.com/questions/2299249/what-is-the-use-of-go-in-sql-server-management-studio&quot;&gt;GO&lt;/a&gt;command. To overcome this we need to first filter out any commands that are unnecessary to maintaining the database and/or will cause issues if invoked as a &lt;em&gt;SqlCommand&lt;/em&gt;. After some experimentation I settled on filtering lines that started with &quot;USE&quot;, &quot;SET&quot;, or starts with &quot;/*&quot; and ends with &quot;*/&quot;. This is specific to the scripts created by SSMS. Further the scripts are broken into batches of commands that can be executed together via a single &lt;em&gt;SqlCommand&lt;/em&gt; by splitting on the GO keyword.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;readonly&lt;/span&gt; Func&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;, &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt;&amp;gt; _startsBatch = s =&amp;gt; s.StartsWith(&lt;span class=&quot;str&quot;&gt;&quot;GO&quot;&lt;/span&gt;, StringComparison.OrdinalIgnoreCase);
&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;readonly&lt;/span&gt; Func&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;, &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt;&amp;gt; _isUse = s =&amp;gt; s.StartsWith(&lt;span class=&quot;str&quot;&gt;&quot;USE&quot;&lt;/span&gt;, StringComparison.OrdinalIgnoreCase);
&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;readonly&lt;/span&gt; Func&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;, &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt;&amp;gt; _isSet = s =&amp;gt; s.StartsWith(&lt;span class=&quot;str&quot;&gt;&quot;SET&quot;&lt;/span&gt;, StringComparison.OrdinalIgnoreCase);
&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;readonly&lt;/span&gt; Func&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;, &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt;&amp;gt; _isComment = s =&amp;gt; s.StartsWith(&lt;span class=&quot;str&quot;&gt;&quot;/*&quot;&lt;/span&gt;) &amp;amp;&amp;amp; s.EndsWith(&lt;span class=&quot;str&quot;&gt;&quot;*/&quot;&lt;/span&gt;);

&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; ExecuteScripts(IEnumerable&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;&amp;gt; scripts)
{
    Func&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;, &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt;&amp;gt; isValidCommand = c =&amp;gt; !_isUse(c) &amp;amp;&amp;amp; !_isSet(c) &amp;amp;&amp;amp; !_isComment(c);
    &lt;span class=&quot;kwrd&quot;&gt;using&lt;/span&gt; (var conn = GetConnection())
    {
        conn.Open();
        &lt;span class=&quot;kwrd&quot;&gt;foreach&lt;/span&gt; (var script &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; scripts)
        {
            var commands = File.ReadAllLines(script).Where(isValidCommand).ToList();
            IEnumerable&amp;lt;IEnumerable&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;&amp;gt;&amp;gt; batches = CreateBatches(commands).ToList();
            &lt;span class=&quot;kwrd&quot;&gt;foreach&lt;/span&gt; (var batch &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; batches)
            {
                &lt;span class=&quot;kwrd&quot;&gt;using&lt;/span&gt; (var query = conn.CreateCommand())
                {
                    query.CommandText = &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;.Join(Environment.NewLine, batch);
                    query.ExecuteNonQuery();
                }
            }
        }
    }
}

&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// In order to execute groups of commands that can be executed together (not all can),&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// we separate them by the GO command into distinct, executable sets.  This assumes&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// that the scripts have been generated by Tasks-&amp;gt;Generate Scripts in SSMS but will&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// also work if each script only contains commands that can be grouped together.&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;param name=&quot;commands&quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; IEnumerable&amp;lt;IEnumerable&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;&amp;gt;&amp;gt; CreateBatches(IEnumerable&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;&amp;gt; commands)
{
    var batch = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; List&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;&amp;gt;();
    &lt;span class=&quot;kwrd&quot;&gt;foreach&lt;/span&gt; (var command &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; commands)
    {
        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (_startsBatch(command))
        {
            &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (batch.Any())
            {
                &lt;span class=&quot;kwrd&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; batch;
                batch = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; List&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;&amp;gt;();
            }
        }
        &lt;span class=&quot;kwrd&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (!&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;.IsNullOrWhiteSpace(command))
        {
            batch.Add(command);
        }
    }

    &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (batch.Any())
    {
        &lt;span class=&quot;kwrd&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; batch;
    }
}&lt;/pre&gt;Now our &lt;em&gt;TestContextBase&lt;/em&gt; is set up to (re)create our database afresh for each test run. This will add a little bit of overhead to our tests runs, but we minimize this by doing it once and it is more than offset by our ability to do TDD on our Dapper-based repositories.&lt;br /&gt;
There are some obvious or apparently obvious opportunities for improvement in the above. First we could maintain many of the settings in a configuration file rather than in code. I chose not to do this because this is test code. It’s really only changing when I’m actively developing the code (and tests) so maintaining changeable settings in a configuration actually doesn’t save us much since we’re modifying the code already.&lt;br /&gt;
&lt;br /&gt;
Another, probably better, opportunity would be to invest in naming conventions – we already have a start on this with the names we’ve used – and standardized locations for our scripts. This would enable use to enumerate them in code at runtime rather than hard-code them in our test context base class. This is something that I would probably do but in a simple case like this I don’t find it necessary. Clearly, we would want to refactor this as the database schema grows.&lt;br /&gt;
&lt;br /&gt;
This wraps up the set up portion of this series. In the &lt;a href=&quot;http://farm-fresh-code.blogspot.com/2014/02/putting-it-all-together-tdd-for-dapper.html&quot;&gt;next post&lt;/a&gt;, I’ll start doing the development of the repositories using TDD based on what we’ve developed so far.</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/7946126290957175480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/02/solving-challenges-of-dapper_11.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/7946126290957175480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/7946126290957175480'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/02/solving-challenges-of-dapper_11.html' title='Solving the Challenges of Dapper Integration Testing: Part 3'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaiW5kKrGK8NEY2971Wm54_LX8PfjBTw7uM3qC3CkHftA7GZ1SWzWkZl75GUBNsqrrwt3bNxEaRDW3O_vRKJ-H3AzmEr3u0O6hMJVpyS4CYtjZeSXQsTUFbKyxUfHTnaySMy8XSrGzOGU/s72-c/dapper-gentleman.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-3211908088226453900</id><published>2014-02-10T07:45:00.001-06:00</published><updated>2014-02-11T13:05:31.477-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Dapper"/><category scheme="http://www.blogger.com/atom/ns#" term="testing"/><title type='text'>Solving the Challenges of Dapper Integration Testing: Part 2</title><content type='html'>&lt;br /&gt;
This is the third in a series of posts on lightweight integration testing with Dapper. These tests are intended to enable us to do Test-Driven Development in creating our Dapper-based repositories. As a reminder our goals – see the first post for the complete explanation – are tests that are:&lt;br /&gt;
&lt;ul&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaiW5kKrGK8NEY2971Wm54_LX8PfjBTw7uM3qC3CkHftA7GZ1SWzWkZl75GUBNsqrrwt3bNxEaRDW3O_vRKJ-H3AzmEr3u0O6hMJVpyS4CYtjZeSXQsTUFbKyxUfHTnaySMy8XSrGzOGU/s1600/dapper-gentleman.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img alt=&quot;A Dapper Gentleman&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaiW5kKrGK8NEY2971Wm54_LX8PfjBTw7uM3qC3CkHftA7GZ1SWzWkZl75GUBNsqrrwt3bNxEaRDW3O_vRKJ-H3AzmEr3u0O6hMJVpyS4CYtjZeSXQsTUFbKyxUfHTnaySMy8XSrGzOGU/s1600/dapper-gentleman.png&quot; title=&quot;&quot; /&gt;&lt;/a&gt;
&lt;li&gt;Automated &lt;/li&gt;
&lt;li&gt;Fast &lt;/li&gt;
&lt;li&gt;Simple &lt;/li&gt;
&lt;li&gt;Minimal Tooling &lt;/li&gt;
&lt;li&gt;Independent &lt;/li&gt;
&lt;li&gt;Self-contained &lt;/li&gt;
&lt;li&gt;Safe &lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
In my &lt;a href=&quot;http://farm-fresh-code.blogspot.com/2014/02/solving-challenges-of-dapper_9.html&quot;&gt;last post&lt;/a&gt; I covered the two easier challenges: providing a database connection in a way that lets us easily substitute our testing database and isolating our tests. Because these are integration tests, the latter is important as the database is a common interaction point for our tests and running them in isolation keeps the test data from one test from causing failures in other tests.&lt;br /&gt;
&lt;br /&gt;
In this post I’m going to cover one of the two remaining challenges: cleaning up test data after each test. We&#39;ll leave the last challenge for the next post.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Data Clean Up&lt;/h3&gt;
&lt;br /&gt;
One of the difficulties with integration tests, especially the isolated kind that I am interested in, is the effort of making sure that your data is set up exactly as you want pre-test. Generally, this will involve writing some code that cleans up any data from previous tests or test runs. This is complicated by relationships in the data, especially in the case where deletes do not cascade. In those cases, a delete can fail when the data in the “child” relation hasn’t been deleted first.&lt;br /&gt;
&lt;br /&gt;
One way to handle this is writing database-specific delete code that understands the relationships and performs deletes in the correct sequence to prevent failures due to non-cascading deletes. To me, this is painful – and certainly not simple.&lt;br /&gt;
&lt;br /&gt;
Another way to handle it would be to simply delete the database tables and related objects between each test run. As we’ll see later, this will be necessary when maintaining currency with the database, but it seems overkill – and certainly slower than we would like, deleting and re-creating the schema per test.&lt;br /&gt;
&lt;br /&gt;
It would be better if we could to leverage the database structure itself to automatically create delete statements in the proper order. Rather than writing the code once-per database, we could write the code once per database provider and it would suffice for most, if not all, databases that use that provider. At least it would suffice for the kinds of databases that I’m concerned with most of the time.&lt;br /&gt;
&lt;br /&gt;
This idea is not original with me and I didn’t want to reinvent the wheel if I could possibly avoid it so I did a bit of research into automated integration testing. During my research, I came across a &lt;a href=&quot;https://gist.github.com/jbogard/5805783&quot; title=&quot;Database Deleter Gist&quot;&gt;DatabaseDeleter&lt;/a&gt; class by &lt;a href=&quot;http://lostechies.com/jimmybogard/&quot;&gt;Jimmy Bogard&lt;/a&gt;, who blogs at &lt;a href=&quot;http://lostechies.com/&quot;&gt;LosTechies.com&lt;/a&gt;, that I thought was the perfect solution to the problem of automatically cleaning up data generated in an integration test. The only problem – it was written for use with &lt;a href=&quot;http://nhforge.org/&quot; rel=&quot;nofollow&quot;&gt;nHibernate&lt;/a&gt;. I adapted it to work using &lt;em&gt;SqlConnection&lt;/em&gt; and &lt;em&gt;SqlCommand&lt;/em&gt; for Microsoft SQL Server (the version I’m using is Microsoft SQL Server 2012).&lt;br /&gt;
&lt;br /&gt;
The most interesting method is the &lt;em&gt;BuildTableList&lt;/em&gt; method (full code is available on &lt;a href=&quot;https://github.com/tvanfosson/dapper-integration-testing&quot; title=&quot;Dapper Integration Testing repository on GitHub&quot;&gt;GitHub&lt;/a&gt;):&lt;b&gt;BuildTableList&lt;/b&gt;&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; IEnumerable&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;&amp;gt; BuildTableList(ICollection&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;&amp;gt; allTables,
                                                  ICollection&amp;lt;Relationship&amp;gt; allRelationships)
{
    var tablesToDelete = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; List&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;&amp;gt;();

    &lt;span class=&quot;kwrd&quot;&gt;while&lt;/span&gt; (allTables.Any())
    {
        var leafTables = allTables.Except(allRelationships
                                  .Select(rel =&amp;gt; rel.PrimaryKeyTable))
                                  .ToArray();

        tablesToDelete.AddRange(leafTables);

        &lt;span class=&quot;kwrd&quot;&gt;foreach&lt;/span&gt; (var leafTable &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; leafTables)
        {
            allTables.Remove(leafTable);

            var relToRemove = allRelationships.Where(rel =&amp;gt; rel.ForeignKeyTable == leafTable)
                                              .ToArray();

            &lt;span class=&quot;kwrd&quot;&gt;foreach&lt;/span&gt; (var rel &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; relToRemove)
            {
                allRelationships.Remove(rel);
            }
        }
    }

    &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; tablesToDelete;
}&lt;/pre&gt;
&lt;br /&gt;
This method takes a collection of tables (all the tables in the database) and a collection of parent-child relationships between tabels. If you think of the relationships as forming a set of trees, it performs a bottom-up traversal across these trees, adding the leaf nodes discovered in each pass to an ordered list of tables to delete data from. Simultaneously, it removes those leaf nodes from the trees, by removing the relationships and removing the tables from the set of tables to consider, so that in the next pass the parents of those leaf nodes become the new leaf nodes. In this way, if we delete data from the ordered table collection in order, we are guaranteed to not violate any foreign key constraints. This gives us a safe order in which to build the delete commands to avoid failures.&lt;br /&gt;
&lt;br /&gt;
This collection is used by &lt;em&gt;BuildDeleteTables&lt;/em&gt; to generate the delete command associated with a particular database. This is constructed once per test run and subsequently reused per test clean up to remove any data that the test may have added.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;BuildDeleteTables/BuildDeleteSql&lt;/strong&gt;&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; BuildDeleteTables()
{
    &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (_initialized.Contains(_database))
    {
        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt;;
    }

    &lt;span class=&quot;kwrd&quot;&gt;lock&lt;/span&gt; (_lockObj)
    {
        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (!_initialized.Add(_database))
        {
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt;;
        }

        &lt;span class=&quot;kwrd&quot;&gt;using&lt;/span&gt; (var connection = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; SqlConnection(_database))
        {
            connection.Open();

            var allTables = GetAllTables(connection);

            var allRelationships = GetRelationships(connection);

            _tablesToDelete = BuildTableList(allTables, allRelationships);

            _deleteSql[_database] = BuildTableSql(_tablesToDelete);
        }
    }
}

&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; BuildTableSql(IEnumerable&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;&amp;gt; tablesToDelete)
{
    &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;.Join(&lt;span class=&quot;str&quot;&gt;&quot; &quot;&lt;/span&gt;, tablesToDelete.Select(t =&amp;gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;.Format(&lt;span class=&quot;str&quot;&gt;&quot;delete from [{0}];&quot;&lt;/span&gt;, t)));
}&lt;/pre&gt;
The &lt;i&gt;DatabaseDeleter&lt;/i&gt; class is used in the &lt;i&gt;Dispose&lt;/i&gt; method (following &lt;a href=&quot;http://lostechies.com/chrispatterson/&quot;&gt;Chris Patterson’s&lt;/a&gt; &lt;a href=&quot;http://lostechies.com/chrispatterson/2012/11/29/idisposable-done-right/&quot;&gt;IDisposable Done Right&lt;/a&gt; pattern) in our abstract &lt;i&gt;TestContextBase&lt;/i&gt; class.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;TestContextBase&lt;/strong&gt; (Dispose implementation)&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; TestContextBase : IDisposable
{
    &lt;span class=&quot;rem&quot;&gt;// Remainder of class omitted for brevity&lt;/span&gt;
    
    &lt;span class=&quot;rem&quot;&gt;// IDisposable implementation. On dispose of the context, we clean up any data inserted by the test&lt;/span&gt;
    
    &lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; _disposed;

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Dispose()
    {
        Dispose(&lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;);
        GC.SuppressFinalize(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;);
    }

    ~TestContextBase()
    {
        Dispose(&lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;);
    }

    &lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Dispose(&lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; disposing)
    {
        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (_disposed)
        {
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt;;
        }

        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (disposing)
        {
            var deleter = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; DatabaseDeleter(_connectionString);
            deleter.DeleteAllData();
        }

        _disposed = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
    }
}&lt;/pre&gt;
The &lt;em&gt;Dispose&lt;/em&gt; method is invoked in our test classes in the clean up method, which we’ve seen before, but is now shown with the context-related code for a sample &lt;em&gt;DapperUserRepository&lt;/em&gt; below. After each test, the test context is disposed, and the &lt;i&gt;DeleteAllData&lt;/i&gt; for the related database is run, cleaning up any data that was inserted by the test.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;[TestInitialize]
&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Init()
{
    Start();
    _c = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; DapperUserRepositoryTestContext();
}

[TestCleanup]
&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Cleanup()
{
    &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (_c != &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)
    {
        _c.Dispose();
    }
    End();
}&lt;/pre&gt;
That wraps up our data clean up task. Using our base test context and it&#39;s &lt;i&gt;IDisposable&lt;/i&gt;&amp;nbsp;implementation lets us make sure that each test starts with a clean database, as long as our clean up method runs (see the discussion in first post in the series).&amp;nbsp;&lt;a href=&quot;http://farm-fresh-code.blogspot.com/2014/02/solving-challenges-of-dapper_11.html&quot;&gt;Next time&lt;/a&gt; we&#39;ll see how to handle creating the database schema so that our test database is automatically set up for each test run as our database changes.</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/3211908088226453900/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/02/solving-challenges-of-dapper.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/3211908088226453900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/3211908088226453900'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/02/solving-challenges-of-dapper.html' title='Solving the Challenges of Dapper Integration Testing: Part 2'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaiW5kKrGK8NEY2971Wm54_LX8PfjBTw7uM3qC3CkHftA7GZ1SWzWkZl75GUBNsqrrwt3bNxEaRDW3O_vRKJ-H3AzmEr3u0O6hMJVpyS4CYtjZeSXQsTUFbKyxUfHTnaySMy8XSrGzOGU/s72-c/dapper-gentleman.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-3316118326397420731</id><published>2014-02-09T09:28:00.001-06:00</published><updated>2014-02-10T08:50:35.739-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Dapper"/><category scheme="http://www.blogger.com/atom/ns#" term="testing"/><title type='text'>Solving the Challenges of Dapper Integration Testing: Part 1</title><content type='html'>In my&lt;a href=&quot;http://farm-fresh-code.blogspot.com/2014/02/lightweight-integration-testing-with.html&quot;&gt; last post&lt;/a&gt; I outlined the series of events that led me to want to write some lightweight integration tests for Dapper that would allow me to develop my &lt;a href=&quot;https://code.google.com/p/dapper-dot-net/&quot;&gt;Dapper&lt;/a&gt; repositories using Test-Driven Development (TDD). These tests wouldn&#39;t replace application-level integration tests, but would allow me to &quot;unit test&quot; my Dapper code so that I could develop it in a test-driven manner. My implementation would have to meet several requirements (see my previous post for a fuller explanation):&lt;br /&gt;
&lt;div style=&quot;text-align: right;&quot;&gt;
&lt;/div&gt;
&lt;ul&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaiW5kKrGK8NEY2971Wm54_LX8PfjBTw7uM3qC3CkHftA7GZ1SWzWkZl75GUBNsqrrwt3bNxEaRDW3O_vRKJ-H3AzmEr3u0O6hMJVpyS4CYtjZeSXQsTUFbKyxUfHTnaySMy8XSrGzOGU/s1600/dapper-gentleman.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img alt=&quot;A Dapper Gentleman&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaiW5kKrGK8NEY2971Wm54_LX8PfjBTw7uM3qC3CkHftA7GZ1SWzWkZl75GUBNsqrrwt3bNxEaRDW3O_vRKJ-H3AzmEr3u0O6hMJVpyS4CYtjZeSXQsTUFbKyxUfHTnaySMy8XSrGzOGU/s1600/dapper-gentleman.png&quot; title=&quot;&quot; /&gt;&lt;/a&gt;
&lt;li&gt;Automated &lt;/li&gt;
&lt;li&gt;Fast &lt;/li&gt;
&lt;li&gt;Simple &lt;/li&gt;
&lt;li&gt;Minimal Tooling &lt;/li&gt;
&lt;li&gt;Independent &lt;/li&gt;
&lt;li&gt;Self-contained &lt;/li&gt;
&lt;li&gt;Safe &lt;/li&gt;
&lt;/ul&gt;
Achieving these requirements could be a challenge with integration tests. I outlined several challenges that I would face including automatically setting up the database, cleaning up data between tests, isolating the operations of the tests, and programmatically providing a connection to the repository that could be mocked out. In this post I will describe how I addressed each of these challenges, including the code I created or adapted to use for my scenario.&lt;br /&gt;
&lt;br /&gt;
All of the code for these examples can be found at &lt;a href=&quot;https://github.com/tvanfosson/dapper-integration-testing&quot; title=&quot;Dapper Integration Testing Github repository&quot;&gt;https://github.com/tvanfosson/dapper-integration-testing&lt;/a&gt;. The inline code snippets may omit some details to save space but you can find the complete code in the repository.&lt;br /&gt;
&lt;br /&gt;
Let&#39;s take them from simplest to most complex.&amp;nbsp; In this post we’ll cover providing a connection and isolating the execution of the tests from each other.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Providing a Connection&lt;/h3&gt;
&lt;br /&gt;
Our repository will function as a &quot;repository of queries.&quot; Each method encapsulates some query or command that interacts with the database. In some cases it might be several queries that function to provide complex data or complete a complex transaction. Importantly, each method in our repository will function as an independent unit of work. In this case, rather than provide a connection to the repository, instead we want to provide a mechanism to obtain a connection that can be created and disposed within the context of a single method.&lt;br /&gt;
&lt;br /&gt;
We will use dependency injection to provide an &lt;i&gt;IConnectionFactory instance&lt;/i&gt;. In production, the connection factory will be hooked up in our dependency injection framework to provide connections to our database provider of choice. As long as that provider supports &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.data.common.dbconnection.aspx&quot; rel=&quot;nofollow&quot; title=&quot;DbConnection documentation on MSDN&quot;&gt;&lt;em&gt;DbConnection&lt;/em&gt;&lt;/a&gt;, it will work for our purposes. Since Dapper requires this to function, that doesn&#39;t restrict our choices of provider any more than the choice of Dapper itself does. &lt;em&gt;IConnectionFactory&lt;/em&gt; needs only one method, &lt;span style=&quot;text-wrap: none; white-space: nowrap;&quot;&gt;&lt;i&gt;Create(string connectionStringName)&lt;/i&gt;&lt;/span&gt;, which takes the name of a connection string and provides a &lt;em&gt;DbConnection&lt;/em&gt; to the provider specified by the connection string. In practices, our implementations of this class will likely be dependent on some configuration wrapper that allows it to retrieve the named connection string from a configuration file.&lt;br /&gt;
We&#39;ll provide a base class for our repositories that uses the factory and makes it available to all repositories derived from it.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;IConnectionFactory&lt;/b&gt;&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;interface&lt;/span&gt; IConnectionFactory
{
    DbConnection Create(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; connectionStringName);
}&lt;/pre&gt;
And here is one possible implementation for a SqlServer-backed repository using a configuration wrapper (code not shown).&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; MsSqlConnectionFactory : IConnectionFactory
{
    &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;readonly&lt;/span&gt; IConfiguration _configuration;

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; MsSqlConnectionFactory(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; DbConnection Create(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; connectionStringName)
    {
        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; SqlConnection(_configuration.GetConnectionString(connectionStringName));
    }
}&lt;/pre&gt;
&lt;b&gt;DapperRepositoryBase&lt;/b&gt; (constructor)&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; DapperRepositoryBase
{
    &lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;readonly&lt;/span&gt; IConnectionFactory _connectionFactory;
    &lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; _connectionStringName;

    &lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; DapperRepositoryBase(IConnectionFactory connectionFactory, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; connectionStringName)
    {
        _connectionFactory = connectionFactory;
        _connectionStringName = connectionStringName;
    }
    
    &lt;span class=&quot;rem&quot;&gt;// remainder omitted&lt;/span&gt;
}&lt;/pre&gt;
In our tests we will use a SqlServer LocalDB instance added to the test project as a content item. Each of our test classes will have a test context that provides a mechanism to obtain the connection factory and pass back a mock that will return a connection to our LocalDB instance. We’ll see more of this test context base class later as it provides additional common behavior to support our test classes. Notice that it’s internal – it’s not needed outside our test project – and it implements &lt;i&gt;IDisposable&lt;/i&gt;. That will be important later, but I&#39;m not going to give it away how just yet.&lt;br /&gt;
&lt;br /&gt;
Note: I’m using &lt;a href=&quot;http://fakeiteasy.github.io/&quot;&gt;FakeItEasy&lt;/a&gt;, a dead-simple to use dynamic fake framework to provide a mock connection factory. Since these are integration tests, this is the only usage we’re likely to see.&amp;nbsp; I’ve got it set up to provide a new connection instance every time it’s called since that’s the way our real implementations will work.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;TestContextBase&lt;/b&gt;&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; TestContextBase : IDisposable
{
    &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; _dbFile = Path.Combine(Environment.CurrentDirectory,
                                                          &lt;span class=&quot;str&quot;&gt;&quot;DapperTestingDB.mdf&quot;&lt;/span&gt;);
    &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; _connectionString =
        &lt;span class=&quot;str&quot;&gt;@&quot;Data Source=(LocalDB)\v11.0;Initial Catalog=DapperTesting;&quot;&lt;/span&gt;
        + &lt;span class=&quot;str&quot;&gt;&quot;Integrated Security=True;AttachDbFilename=&quot;&lt;/span&gt;
        + _dbFile;

    &lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; DbConnection GetConnection()
    {
        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; SqlConnection(_connectionString);
    }

    &lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; IConnectionFactory CreateConnectionFactory(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; connectionStringName)
    {
        var connectionFactory = A.Fake&amp;lt;IConnectionFactory&amp;gt;();

        A.CallTo(() =&amp;gt; connectionFactory.Create(connectionStringName))
         .ReturnsLazily(f =&amp;gt; GetConnection());

        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; connectionFactory;
    }
    
    &lt;span class=&quot;rem&quot;&gt;// Disposable implementation omitted (we&#39;ll see it later)&lt;/span&gt;
}&lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;
Isolating Test Execution&lt;/h3&gt;
&lt;br /&gt;
Because our tests are touching the same database, there’s a strong likelihood that we could get inconsistent or incorrect results if more than one test runs at a specific time. A test that inserts some data in the database, then runs a query against it may get different data than expected if another test, running at the same time, also inserts some data into the same tables being queried by the first test. To prevent this, we want to make sure that our tests run serially, one after the other, instead of in parallel.&lt;br /&gt;
&lt;br /&gt;
One way to do this is to use &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms182631.aspx&quot; rel=&quot;nofollow&quot; title=&quot;How to Create an Ordered Test&quot;&gt;Ordered Tests&lt;/a&gt;. This will force the tests to run in a specific order and, if we check the &lt;i&gt;Continue after failure&lt;/i&gt; option, this should give us what we want, a way to run independent tests in an execution-isolated way. Doing this, however, adds some manual operations to maintaining our test suite and prevents us from simply running these tests along with our other (unit) tests in the same way that we are used to. My preference is to use the &lt;i&gt;TestInitialze&lt;/i&gt; and &lt;i&gt;TestCleanup&lt;/i&gt; methods with some synchronization code to enforce execution-isolation. To do that, I create a &lt;i&gt;TestBase&lt;/i&gt; class that all of my test classes will derive from. This class will contain &lt;i&gt;Start&lt;/i&gt; and &lt;i&gt;Stop&lt;/i&gt; methods that can be used by our setup/teardown methods in the test class to enforce a single thread of execution through the test suite using a &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.threading.monitor.aspx&quot; rel=&quot;nofollow&quot; title=&quot;Monitor documentation on MSDN&quot;&gt;&lt;i&gt;Monitor&lt;/i&gt;&lt;/a&gt;.  Using a &lt;i&gt;Monitor&lt;/i&gt; with a shared lock object will allow our tests to synchronize themselves through test setup/teardown.&lt;br /&gt;
&lt;br /&gt;
Note: one downside to this method is that it may be possible for certain types of exceptions to fail our tests in a way that the teardown code does not get called. In this case, our tests will hang. This could be a problem if you do continuous integration and check in code that fails in that particular way. This should only happen in failure conditions, not when your tests are passing. You do make sure your tests pass before you check code into your repositories, don&#39;t you? The trade-off of being able to use my normal unit testing processes for these tests as well is worth the potential risk to me.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;TestBase&lt;/b&gt;&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; TestBase
{
    &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; _lock = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt;();

    &lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Start()
    {
        Monitor.Enter(_lock);
    }

    &lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; End()
    {
        Monitor.Exit(_lock);
    }
}&lt;/pre&gt;
&lt;b&gt;Example set up and teardown&lt;/b&gt;&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;[TestInitialize]
&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Init()
{
    Start();
    &lt;span class=&quot;rem&quot;&gt;// create our concrete test context&lt;/span&gt;
}

[TestCleanup]
&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Cleanup()
{
    &lt;span class=&quot;rem&quot;&gt;// dispose of our concrete test context&lt;/span&gt;
    End();
}&lt;/pre&gt;
That wraps it up for this post, in future posts I&#39;ll tackle &lt;a href=&quot;http://farm-fresh-code.blogspot.com/2014/02/solving-challenges-of-dapper.html&quot;&gt;data clean up&lt;/a&gt;, then database set up. These will require more complex solutions and some convention-based programming.</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/3316118326397420731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/02/solving-challenges-of-dapper_9.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/3316118326397420731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/3316118326397420731'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/02/solving-challenges-of-dapper_9.html' title='Solving the Challenges of Dapper Integration Testing: Part 1'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaiW5kKrGK8NEY2971Wm54_LX8PfjBTw7uM3qC3CkHftA7GZ1SWzWkZl75GUBNsqrrwt3bNxEaRDW3O_vRKJ-H3AzmEr3u0O6hMJVpyS4CYtjZeSXQsTUFbKyxUfHTnaySMy8XSrGzOGU/s72-c/dapper-gentleman.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-6577478566727483373</id><published>2014-02-08T15:04:00.000-06:00</published><updated>2014-10-07T08:47:32.327-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Dapper"/><category scheme="http://www.blogger.com/atom/ns#" term="testing"/><title type='text'>Lightweight Integration Testing with Dapper</title><content type='html'>&lt;h2&gt;Motivation, Requirements, and Challenges&lt;/h2&gt;&lt;br /&gt;
&lt;h3&gt;Motivation&lt;/h3&gt;&lt;br /&gt;
Recently I worked on a project that used Dapper as the data access layer, creating repositories based on Dapper queries for each aggregate root in the domain model. Dapper (&lt;a href=&quot;https://github.com/StackExchange/dapper-dot-net&quot;&gt;https://github.com/StackExchange/dapper-dot-net&lt;/a&gt;) if you aren&#39;t aware, is &quot;a simple object mapper for .Net.&quot; Dapper was developed for and is used on &lt;a href=&quot;http://stackoverflow.com/&quot; rel=&quot;nofollow&quot; title=&quot;StackOverflow&quot;&gt;StackOverflow.com&lt;/a&gt;. Because it&#39;s built as extensions to &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.data.common.dbconnection.aspx&quot; rel=&quot;nofollow&quot; title=&quot;DbConnection Documentation at MSDN&quot;&gt;DbConnection&lt;/a&gt; it isn&#39;t &lt;br /&gt;
&lt;img alt=&quot;A Dapper Gentleman&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaiW5kKrGK8NEY2971Wm54_LX8PfjBTw7uM3qC3CkHftA7GZ1SWzWkZl75GUBNsqrrwt3bNxEaRDW3O_vRKJ-H3AzmEr3u0O6hMJVpyS4CYtjZeSXQsTUFbKyxUfHTnaySMy8XSrGzOGU/s1600/dapper-gentleman.png&quot; title=&quot;&quot; style=&quot;float: right;&quot; /&gt; tied to any specific database and works with a variety of database providers. There are some micro-ORM implementations built on top of Dapper, but we used it directly. In it&#39;s base form, Dapper consists of generic query/execute methods that take SQL statements as a string, run the SQL on the database, and map the resulting output to either a collection of objects (type specified in the call) or as a count of the results returned.&lt;br /&gt;
&lt;br /&gt;
Dapper is pretty simple and simple to use. That&#39;s one of the reasons that it is also pretty fast. That was the reason that we chose to use it. I say &quot;we&quot;, but really the decision had been made prior to my involvement in the project and my involvement was limited to extending the implementation for more use cases. Because it&#39;s simple, you might be able to convince yourself of the correctness of your implementations and may not design any specific tests for your repositories.&lt;br /&gt;
&lt;br /&gt;
That was the situation I found when I joined the project. There were plenty of unit tests, but they stopped at the repository layer. All of the Dapper-based repositories had interfaces and those interfaces were mocked in the unit tests. There were no tests - unit or integration - for the repositories themselves. Again, the queries were pretty simple, so code inspection was used to verify correctness along with an extensive QA process.&lt;br /&gt;
&lt;br /&gt;
That is, until I added a feature that required more complex behavior, specifically a relation that had some rather complex logic that involved left joins, multiple result sets, and transactional behavior. Dapper was able to handle all that I threw at it, but I felt uncomfortable that (1) the only testing that my queries had was my own manual, exploratory testing and (2) I&#39;d need to be careful to manually test around any code changes that I wanted to make.&lt;br /&gt;
&lt;br /&gt;
Because Dapper is implemented as extension methods, it doesn&#39;t lend it self to mocking and I didn&#39;t really want to introduce another layer around Dapper that would have similar problems. Moreover, I felt that I needed to not only verify that my SQL commands were being execute but also that my SQL actually did what I expected. What I really wanted/needed was a set of lightweight integration tests that would be performed against a test database, ideally with a minimum amount of manual set up, that could be executed as if they were unit tests.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Requirements&lt;/h3&gt;&lt;h4&gt;Automated&lt;/h4&gt;For me, for tests to be useful, they need to be automated. I wanted these tests to be able be run along side my true unit tests.&lt;br /&gt;
&lt;h4&gt;Fast&lt;/h4&gt;Because I wanted the tests to run regularly, they need to be reasonably fast. The tests can&#39;t be too big or too extensive. Simple, usable tests against a local database are my ideal.&lt;br /&gt;
&lt;h4&gt;Simple&lt;/h4&gt;I&#39;m not looking to replace acceptance tests or the real integration tests for the application. Keeping the tests simple will help keep them fast. Keeping them simple also means having to develop the minimum amount of code to create a new test.&lt;br /&gt;
&lt;h4&gt;Minimal Tooling&lt;/h4&gt;I want these to run on any developer&#39;s machine and, potentially, on a build or continuous integration server.&lt;br /&gt;
&lt;h4&gt;Independent&lt;/h4&gt;In the spirit of unit tests, each test should be independent. The data created for and by the test should be unavailable and should not interfere with other tests. The tests should be able to run in any order. To keep things as simple as possible, though, we&#39;ll relax this constraint for catastrophic failures. Basically, when the per-test clean up tasks runs, we want to guarantee that each test gets a fresh start.&lt;br /&gt;
&lt;h4&gt;Self-contained&lt;/h4&gt;Tests, or the context they are run in, will perform any data set up required for the test. There should be no manual steps or external scripts that need to be invoked before the tests can be run. Any database or data set up that needs to be done, including any scripts that need to execute, should be performed by the test code.&lt;br /&gt;
&lt;h4&gt;Safe&lt;/h4&gt;Because these tests are going to be used to develop code, the environment that they run in should be isolated. The tests shouldn&#39;t connect directly to other application databases, even to read data, to maximize safety.&lt;br /&gt;
&lt;br /&gt;
Based on these requirements I created the tests in a unit test project. Each repository gets it&#39;s own test class. I opted to go with &lt;a href=&quot;http://technet.microsoft.com/en-us/library/hh510202.aspx&quot; rel=&quot;nofollow&quot; title=&quot;LocalDB documentation on TechNet&quot;&gt;LocalDB&lt;/a&gt; as the database provider. I added the MDF file (and log) to the test project as a content item, updated when newer. Using a unit test project will allow me to tie into the standard test running and ensure that my Dapper integration tests are performed along with the rest of my unit tests. Using LocalDB will keep my tests isolated.&lt;br /&gt;
&lt;h4&gt;Challenges&lt;/h4&gt;It may not seem obvious at first glance but these choices along with the requirements and good software practices raise some interesting challenges.&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Creating the database schema. To be self-contained, our test framework will need a way to ensure that the database has the correct tables and other database objects for each test run. &lt;/li&gt;
&lt;li&gt;Data clean up. We could have each test be responsible for cleaning up after itself but in order to keep them simple I think we can do better. We want an automated method to remove data, including relational data, created by any of our tests that can run in the test clean up phase. &lt;/li&gt;
&lt;li&gt;Test isolation. Because the tests need to be independent and yet share a database, we need to ensure that they are run sequentially, including initialization and clean up tests. Different unit test runners may or may not guarantee the behavior that we need so we need a mechanism to guarantee this regardless of the test runner. &lt;/li&gt;
&lt;li&gt;Providing a connection to a repository for use during the test that doesn&#39;t rely on any manual configuration yet maintains good development practices. &lt;/li&gt;
&lt;/ol&gt;In my &lt;a href=&quot;http://farm-fresh-code.blogspot.com/2014/02/solving-challenges-of-dapper_9.html&quot;&gt;next post&lt;/a&gt; I will detail the solutions to two of the challenges I&#39;ve presented and get a start on the code required to implement the solution.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/6577478566727483373/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/02/lightweight-integration-testing-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/6577478566727483373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/6577478566727483373'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2014/02/lightweight-integration-testing-with.html' title='Lightweight Integration Testing with Dapper'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaiW5kKrGK8NEY2971Wm54_LX8PfjBTw7uM3qC3CkHftA7GZ1SWzWkZl75GUBNsqrrwt3bNxEaRDW3O_vRKJ-H3AzmEr3u0O6hMJVpyS4CYtjZeSXQsTUFbKyxUfHTnaySMy8XSrGzOGU/s72-c/dapper-gentleman.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-5086819409798946044</id><published>2013-06-21T10:14:00.000-05:00</published><updated>2013-06-21T10:14:56.378-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="EF5"/><category scheme="http://www.blogger.com/atom/ns#" term="Entity Framework"/><category scheme="http://www.blogger.com/atom/ns#" term="MiniProfiler"/><category scheme="http://www.blogger.com/atom/ns#" term="WebAPI"/><title type='text'>Getting MiniProfiler to work with WebAPI and EF5 Code First</title><content type='html'>I have, in my head, a set of technologies that are candidates to add to my regular toolset. One of those tools is &lt;a href=&quot;http://miniprofiler.com/&quot; target=&quot;_blank&quot;&gt;MiniProfiler&lt;/a&gt;.&amp;nbsp; MiniProfiler has been around for awhile and, truth to be told, I did spend some time trying to get it to work a little over a year ago. Long enough ago such that I no longer remember why I couldn’t get it to work, but short enough that I do remember having problems with it. Since then I’ve switched jobs and have been working on a project where introducing MiniProfiler wasn’t really possible so I put the tool back on the shelf. Partly because it’s always bugged me that I never got it working for me and partly because it looks like it might now come in handy on a project, I decided to get back on the horse, as it were and get it figured out.&lt;br /&gt;
&lt;br /&gt;
Let me first say that the &lt;a href=&quot;http://miniprofiler.com/&quot; target=&quot;_blank&quot;&gt;online documentation&lt;/a&gt; is excellent and comprehensive, it does look a bit out of date. Currently the instructions are for Entity Framework 4.1 and 4.2.&amp;nbsp; As of this writing I’m using EF5 and CTPs of EF6 are available.&amp;nbsp; Fortunately, the instructions – minus the caveats for 4.2 – work pretty well.&amp;nbsp; In fact, all of the information you need to use MiniProfiler with WebAPI and EF5 Code First is contained in the documentation, but not always where you would expect.&lt;br /&gt;
&lt;br /&gt;
Also, if you’re like me, you’ve gotten used to just installing NuGet packages and using them without a lot of extra configuration. That’s not the case here. &lt;em&gt;It’s important to read all of the instructions for installing and configuring the MiniProfiler for use.&lt;/em&gt; There’s a fair amount of hand-crafted set up that you will need to make it work, not all of it listed in the Getting Started section of the documentation.&lt;br /&gt;
&lt;br /&gt;
Start by adding the MiniProfilerEF &lt;a href=&quot;http://nuget.org/&quot; target=&quot;_blank&quot;&gt;NuGet&lt;/a&gt; package to your solution. I used version 2.1 (published on 3/4/2013). It has a dependency on the MiniProfiler package (also version 2.1, published on the same date) so you will get both when installing the Entity Framework integration.&lt;br /&gt;
&lt;br /&gt;
Next up, you’ll need a web page.&amp;nbsp; Fortunately, my WebAPI project came with an MVC home controller equipped with an Index action and associated view. For my exploration I made use of this set up. In &lt;span style=&quot;font-family: Courier New;&quot;&gt;Views\Shared\_Layout.cshtml&lt;/span&gt; I added the following (I’ve included a bit of context). Note that I inserted the MiniProfiler scripts after jQuery and before any page-specific scripts are included.&amp;nbsp; MiniProfiler requires jQuery 1.7+ and will attempt to load it if it isn’t installed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
    @using StackExchange.Profiling  &lt;span class=&quot;rem&quot;&gt;&lt;!-- Added for MiniProfiler --&gt;&lt;/span&gt;
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
         ...
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
        ... content ...
  
        @RenderBody()

        @Scripts.Render(&quot;~/bundles/jquery&quot;)

        @MiniProfiler.RenderIncludes()  &lt;span class=&quot;rem&quot;&gt;&lt;!-- Added for MiniProfiler --&gt;&lt;/span&gt;

        @RenderSection(&quot;scripts&quot;, required: false)
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
In addition to this, I had to make a change to my web.config file, adding the handler for the MiniProfiler resources (that is the CSS and JavaScript files used to render the results, located at &lt;span style=&quot;font-family: Courier New;&quot;&gt;/mini-profiler-resources/…&lt;/span&gt; ).&amp;nbsp; I added the following to the default web.config in the &lt;span style=&quot;font-family: Courier New;&quot;&gt;/system.webServer/handlers&lt;/span&gt; section.&amp;nbsp; This bit is listed in the troubleshooting section of the documentation and it was required even though my web.config did not have &lt;span style=&quot;font-family: Courier New;&quot;&gt;runAllManagedModulesForAllRequests=false&lt;/span&gt;. Extension-less handling for MVC is enabled in my configuration via handlers, not by setting the value of that parameter to &lt;span style=&quot;font-family: Courier New;&quot;&gt;true&lt;/span&gt; and thus I needed to add the MiniProfiler handler manually.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;MiniProfiler&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;mini-profiler-resources/*&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;verb&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;*&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;System.Web.Routing.UrlRoutingModule&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;resourceType&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Unspecified&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;preCondition&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;integratedMode&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
Now that the MVC application is set up to display the MiniProfiler results, it’s time to enable it in the application.  For Entity Framework, this is the easy part.  Simply add the initialization to the &lt;span style=&quot;font-family: Courier New;&quot;&gt;Application_Start&lt;/span&gt; method in &lt;span style=&quot;font-family: Courier New;&quot;&gt;Global.asax.cs&lt;/span&gt;, then initiate the collection of profiling data in &lt;span style=&quot;font-family: Courier New;&quot;&gt;Application_BeginRequest&lt;/span&gt; and stop the profiler in &lt;span style=&quot;font-family: Courier New;&quot;&gt;Application_EndRequest&lt;/span&gt;.  I’ll note that I found I did not have to specify the &lt;span style=&quot;font-family: Courier New;&quot;&gt;SqlServerFormatter&lt;/span&gt; explicitly to get SQL commands that were readable and usable with SQL Server Management Studio (when no formatter is supplied, the raw SQL command is used). That may not be the case for all providers or different versions of Entity Framework.  If so, simply uncomment the line setting the formatter.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; WebApiApplication : System.Web.HttpApplication
{
    &lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Application_Start()
    {
        ...
        
        &lt;span class=&quot;rem&quot;&gt;//MiniProfiler.Settings.SqlFormatter = new StackExchange.Profiling.SqlFormatters.SqlServerFormatter();&lt;/span&gt;
        MiniProfilerEF.Initialize();
    }

    &lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Application_BeginRequest()
    {
        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (Request.IsLocal)
        {
            MiniProfiler.Start();
        }
    }

    &lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Application_EndRequest()
    {
        MiniProfiler.Stop();
    }
}&lt;/pre&gt;
&lt;br /&gt;
Note also, that the pre-condition for running the profiler is that the request be a &lt;strong&gt;local&lt;/strong&gt; request. If you plan on running this in a performance test environment, you’ll need to modify the condition for starting the profiler. I will probably drive it with values from the web.config file (&lt;em&gt;AppSettings&lt;/em&gt;). See the &lt;a href=&quot;http://miniprofiler.com/&quot; target=&quot;_blank&quot;&gt;documentation&lt;/a&gt; for more configuration options and usage for more complex examples.&lt;br /&gt;
&lt;br /&gt;
The final step is to write the code to query your API from /home/ and observe the results. I picked a simple WebAPI &lt;a href=&quot;http://www.asp.net/web-api/overview/creating-web-apis/using-web-api-with-entity-framework/using-web-api-with-entity-framework,-part-1&quot; target=&quot;_blank&quot;&gt;example&lt;/a&gt; – and implemented part of it. Once I had enough that I could query my API, I executed the project in the debugger and my profiler results showed up on the page in the upper left corner.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNKqNVink6aYaDKpFpF3gzToDxllX9DrJ_qGC7JGamvir3ZOdcrfO7iygFBq_cNXOrEYoo5Z1qKcpl5zp0lYh6ddqXf-SevsjO_0IhdOVmPmxqp8zrhQNZGd3wVm1j2eCXrF8pP9YkzC4/s1600/miniprofiler-capture.PNG&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;377&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNKqNVink6aYaDKpFpF3gzToDxllX9DrJ_qGC7JGamvir3ZOdcrfO7iygFBq_cNXOrEYoo5Z1qKcpl5zp0lYh6ddqXf-SevsjO_0IhdOVmPmxqp8zrhQNZGd3wVm1j2eCXrF8pP9YkzC4/s640/miniprofiler-capture.PNG&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/5086819409798946044/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2013/06/getting-miniprofiler-to-work-with.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/5086819409798946044'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/5086819409798946044'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2013/06/getting-miniprofiler-to-work-with.html' title='Getting MiniProfiler to work with WebAPI and EF5 Code First'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNKqNVink6aYaDKpFpF3gzToDxllX9DrJ_qGC7JGamvir3ZOdcrfO7iygFBq_cNXOrEYoo5Z1qKcpl5zp0lYh6ddqXf-SevsjO_0IhdOVmPmxqp8zrhQNZGd3wVm1j2eCXrF8pP9YkzC4/s72-c/miniprofiler-capture.PNG" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-8143425002321322931</id><published>2012-12-24T12:37:00.002-06:00</published><updated>2012-12-24T12:45:27.984-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Action"/><category scheme="http://www.blogger.com/atom/ns#" term="Factory Pattern"/><title type='text'>Using an Action in a Factory</title><content type='html'>We’ve all seen the Factory (or Factory Method) Pattern. The &lt;a href=&quot;http://en.wikipedia.org/wiki/Factory_method_pattern&quot; target=&quot;_blank&quot;&gt;Factory Pattern&lt;/a&gt; is used to encapsulate the creational logic for a set of related classes, classes that implement a particular interface or inherit from the same base class.&lt;br /&gt;
&lt;br /&gt;
From Wikipedia:&lt;br /&gt;
&lt;blockquote&gt;
The &lt;b&gt;factory method pattern&lt;/b&gt; is an object-oriented creational design pattern to implement the concept of factories and deals with the problem of creating objects (products) without specifying the exact class of object that will be created. The essence of this pattern is to &quot;Define an interface for creating an object, but let the classes that implement the interface decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses.&lt;/blockquote&gt;
One way to implement the pattern is to use a &lt;em&gt;Enum&lt;/em&gt; or some other designator to specify the type of object to be created.&amp;nbsp; The factory method then uses either &lt;em&gt;if&lt;/em&gt; statements or a &lt;em&gt;switch&lt;/em&gt; statement to create the proper type of object or decorate it appropriately based on the setting of the designator. This works well when the creational logic is simple or the number of things created is small. Alternatively, you could have a factory method per type, but that can have the effect of moving the selection logic to the calling class which defeats the purpose.&lt;br /&gt;
&lt;br /&gt;
In answering a recent &lt;a href=&quot;http://stackoverflow.com/questions/14024003/c-sharp-value-reference-passing&quot; target=&quot;_blank&quot;&gt;StackOverflow question&lt;/a&gt; I ran across this issue and it made me think of alternative ways that you could handle this.&amp;nbsp; Using an&lt;em&gt; Action&amp;lt;T&amp;gt;&lt;t&gt;&lt;t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/em&gt;&amp;nbsp;as the designator seemed to me to be a perfect solution in the case in question.&amp;nbsp; Using an &lt;em&gt;Action&lt;/em&gt; allows you to separate the creational logic for each item into a separate method, avoiding overly long &lt;em&gt;switch&lt;/em&gt; or set of &lt;em&gt;if&lt;/em&gt; statements.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; WeaponFactory
{
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; IWeapon Create&amp;lt;T&amp;gt;&lt;t&gt;(Action&amp;lt;T&amp;gt;&lt;t&gt; decorator) &lt;span class=&quot;kwrd&quot;&gt;where&lt;/span&gt; T : IWeapon, &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt;()
    {
        var weapon = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; T();
        decorator(weapon);
        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; weapon;
    }

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; SwordOfDestiny(Sword sword)
    {
        sword.Damage = DamageLevel.Infinite;
    }

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; NormalSword(Sword sword)
    {
    }

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; TinSword(Sword sword)
    {
        sword.Damage = DamageLevel.Minor;
    }
}&lt;/t&gt;&lt;/t&gt;&lt;/pre&gt;
&lt;br /&gt;
Invoked as:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;var weapon = WeaponFactory.Create(WeaponFactory.SwordOfDestiny);&lt;/pre&gt;
&lt;br /&gt;
Using this allows you to keep the creational logic completely separated and avoid the long &lt;em&gt;switch&lt;/em&gt; statement. I’d probably use in conjunction with a dictionary, say &lt;em&gt;Dictionary&lt;person ction=&quot;ction&quot; eapon=&quot;eapon&quot;&gt;&amp;lt;Person,Action&amp;lt;IWeapon&amp;gt;&amp;gt;&lt;/person&gt;&lt;/em&gt;&amp;nbsp;to give me the simplicity of tying the type of the thing to be created to some other aspect/setting and yet still be able to use the decorator pattern within the factory.</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/8143425002321322931/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2012/12/using-action-in-factory.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/8143425002321322931'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/8143425002321322931'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2012/12/using-action-in-factory.html' title='Using an Action&lt;T&gt; in a Factory'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-4109725490407219251</id><published>2012-12-07T16:09:00.001-06:00</published><updated>2012-12-07T17:13:55.096-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Integrity"/><category scheme="http://www.blogger.com/atom/ns#" term="Learning"/><category scheme="http://www.blogger.com/atom/ns#" term="Passion"/><title type='text'>Things My Dogs Teach Me</title><content type='html'>I haven’t written anything for awhile and, though after last night’s deployment I’m not sure I have the capacity to think about code, I did feel that it was time to write something. I’ve been working from home for the past several months. Funny, you would think that would give me more time, but for most of that time I’ve actually been putting more time in on the job with more concentrated effort. One thing it does do, though; it allows me to spend more time in the company of my dogs.&lt;br /&gt;
&lt;br /&gt;
There are two things about my dogs that amaze me and challenge me at the same time.&lt;br /&gt;
&lt;br /&gt;
First, my dogs love to chase squirrels. They live for it. Often I have to get up from my basement office (it’s a split level so I have windows, it’s not as dreary as it sounds) to go let them out for fear that they’ll burst through the back door to get at those pesky lawn rats. The fact that I’ve got a bird feeder in the back yard which is as attractive to the squirrels as it is to the chickadees and nuthatches only increases their opportunities for squirrel chasing.&lt;br /&gt;
&lt;br /&gt;
My dogs love chasing squirrels as much as I love writing code…but they are horrible at it. They have never even come close to catching a squirrel (thankfully). The cat is a different story. We have a regular chipmunk/bird graveyard out back, but I digress. My point is that, despite their repeated failures they have never been tempted to give up on what they love, on the occupation that they were destined for seemingly. Their passion for squirrel chasing surpasses their regular and repeated failures at it.&lt;br /&gt;
&lt;br /&gt;
How is your passion for what you do? You need to tend to your passion. Feed it, encourage it to grow, nurture it. Your passion will sustain you through inevitable times of failure. Every day that I get to write code is a good day. I’m committed to keeping that true by maintaining my passion.&lt;br /&gt;
&lt;br /&gt;
Second, my dogs always know when they’ve done something wrong. They rarely need me to reprimand them. It doesn’t matter how comfortable they’ve been on the couch, when I walk into the room they hop down and slink away without me having to say a word. Now, my dogs aren’t lap dogs and they’ve been taught that furniture is for people (and small animals – I did mention the cat, right). They are clear on the rules. Sometimes they just choose to disobey them when no one is looking.&lt;br /&gt;
&lt;br /&gt;
The important thing or, at least, one important thing is that they aren’t even tempted to shift the blame or deny it when they’ve done something wrong. Oh, that I had as much integrity as my dogs.&lt;br /&gt;
&lt;br /&gt;
How about you? Are you willing to own up to your mistakes? I know that it is a constant challenge to me to not try and find some scapegoat to blame for my errors. Now, I’m not suggesting that we should be like my dogs in that they repeat their mistakes, but integrity demands that we take responsibility for when we mess up. Don’t excuse yourself because others are also culpable (it was the cat!). Don’t try to pretend that it wasn’t you (I see that dog hair on the couch!). Don’t blame the rules or the situation (but the toy poodle gets to get up here!).&amp;nbsp; Own up to it. Accept your responsibility, learn from it, and move on.&lt;br /&gt;
&lt;br /&gt;
Those are just a couple of things I’ve been learning from my dogs. I hope they’ve been helpful to you as well.&amp;nbsp; Next time, I’ll try to have some code for you.</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/4109725490407219251/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2012/12/things-my-dogs-teach-me.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/4109725490407219251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/4109725490407219251'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2012/12/things-my-dogs-teach-me.html' title='Things My Dogs Teach Me'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-5525235145983199236</id><published>2012-08-04T15:20:00.001-05:00</published><updated>2013-01-27T08:56:03.131-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Analytics"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC"/><category scheme="http://www.blogger.com/atom/ns#" term="Attribute"/><title type='text'>Analytics are an aspect</title><content type='html'>On a recent project Jesse Kallhoff, a fellow nerd from &lt;a href=&quot;http://nerdery.com/&quot; target=&quot;_blank&quot;&gt;The Nerdery&lt;/a&gt;, and I were tasked with integrating an existing analytics solution with our extensions to the client’s ASP.NET MVC web site. As it’s a commerce site, the customer’s tracking requirements are extensive.&amp;nbsp; Each page may have unique tracking requirements depending on a variety of conditions, both based on logged in state and query parameters.&amp;nbsp; Moreover, for browse and search pages, there is a tight coupling between the backend search technology and the query parameters supplied as part of the request we are tracking.&lt;br /&gt;
&lt;br /&gt;
Much of the existing code incorporated a series of helpers within each action method, cluttering up the action method with code that wasn’t directly related to the view that was being rendered, but rather was related to the tracking parameters that were going to used by a script on the page to post back to the tracking solution provider.&lt;br /&gt;
&lt;br /&gt;
I was initially tasked with the goal of investigating how we would incorporate analytics into the new pages that we were introducing. I wasn’t familiar with the product the customer had chosen so I dove into the existing code to see how it worked.&amp;nbsp; A familiar pattern appeared.&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Load up some default parameters into the analytics object based on the action being invoked. &lt;/li&gt;
&lt;li&gt;Set/change some parameters based on the search/browse/product context. &lt;/li&gt;
&lt;li&gt;Set some additional parameters based on the users logged in state. &lt;/li&gt;
&lt;li&gt;Dump some scripts on the page, including one script section that defined the parameter and their values that were to be posted back to the tracking provider’s web site via a script request. &lt;/li&gt;
&lt;/ol&gt;
Each action method in the solution repeated this pattern in one form or another, though complicated by some AJAX requests to local actions to retrieve the analytics values stored in local session state once the page was rendered.&lt;br /&gt;
&lt;br /&gt;
I scoped out an an initial solution that would remove the analytics code out of the actions themselves and use action filters to provide, as much as possible, the values required.&amp;nbsp; This was relatively easy to do for items (1) and (3).&amp;nbsp; The filter defined a key that was used to access configuration data to find the default parameters for that action.&lt;br /&gt;
&lt;br /&gt;
NOTE**: the code below is an approximation using the ideas we came up with.&amp;nbsp; Unfortunately I can’t share the actual code with you.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;[Analytics(Key=&lt;span class=&quot;str&quot;&gt;&quot;Browse&quot;&lt;/span&gt;)]
&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; ActionResult Browse( &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; browseContext, ... )
{
...
}&lt;/pre&gt;
&lt;br /&gt;
In the OnActionExecuting method of the filter we use the key to extract the default values associated with the key.&amp;nbsp; We can also check the logged in state and set those parameters as well.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; OnActionExecuting( ActionExecutingContext filterContext )
{
&lt;span class=&quot;kwrd&quot;&gt;    if&lt;/span&gt; (!filterContext.Canceled &amp;amp;&amp;amp; !filterContext.IsChildAction)
    {
&lt;span class=&quot;kwrd&quot;&gt;        if&lt;/span&gt; (filterContext.Result &lt;span class=&quot;kwrd&quot;&gt;is&lt;/span&gt; ViewResultBase) &lt;span class=&quot;rem&quot;&gt;// we only care if we&#39;re delivering HTML&lt;/span&gt;
        {
&lt;span class=&quot;rem&quot;&gt;            // retreive the base analytics object from the configuration&lt;/span&gt;
            var analytics = _analyticsConfiguration.Get(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.Key);
&lt;span class=&quot;kwrd&quot;&gt;            if&lt;/span&gt; (analytics != null) &lt;span class=&quot;rem&quot;&gt;// if we&#39;re doing analytics for this page&lt;/span&gt;
            {
                ... fill &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; user-related parameters from the current session/user&lt;/pre&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;HttpContext.Items[“Analytics”] = analytics;
            }
        }
    }
}&lt;/pre&gt;
&lt;br /&gt;
The difficulty came with (2).&amp;nbsp; It seemed like we would still need to include some code in each action that would be able fill in the request specific context information in the analytics object.&amp;nbsp; To support this, we put the partially filled object into HttpContext.Items where the action could retrieve it as needed to add the parameter-related data.&lt;br /&gt;
&lt;br /&gt;
To address (4), we used the OnActionExecuted method to put the analytics object in the ViewBag so that our master page could render the scripts on the page without using any further AJAX calls.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; OnActionExecuted(ActionExecutedContext filterContext)
{
&lt;span class=&quot;kwrd&quot;&gt;    if&lt;/span&gt; (!filterContext.Canceled &amp;amp;&amp;amp; !filterContext.IsChildAction)
    {
        var result = filterContext.Result &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; ViewResultBase;
&lt;span class=&quot;kwrd&quot;&gt;        if&lt;/span&gt; (result != &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)
        {
            result.ViewBag.Analytics = HttpContext.Items[&lt;span class=&quot;str&quot;&gt;&quot;Analytics&quot;&lt;/span&gt;];
        }
    }
}&lt;/pre&gt;
&lt;br /&gt;
And in the master view:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;@&lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (ViewBag.Analytics != &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)
{
    @Html.AnalyticsAPIScript()
    @Html.AnalyticsDataScript(ViewBag.Analytics)
    ... invoke analytics api ...
}&lt;/pre&gt;
&lt;br /&gt;
This is basically the architecture I had in place on my initial pass. At that point I wasn&#39;t familiar enough with the project to know how to address the browse/search/product details.&amp;nbsp; Before I could develop it further other aspects of the project rose in priority and I moved on to something else. Neither Jesse or I was particularly happy that we still had some analytics code that would be needed in each action, but it was difficult to see how we could avoid without duplicating code from the attribute in the action.&lt;br /&gt;
&lt;br /&gt;
A few weeks later, Jesse took on the completion of the analytics task.&amp;nbsp; This is when one of those cool moments that I’ve come to regularly expect at The Nerdery happened. We were on site at the customer’s office and one evening I get a call from Jesse – he wants to brainstorm on how we were going to address a couple of different aspects of the project, including this one.&amp;nbsp; We spent a couple of hours working through the issues, bouncing ideas off each other back and forth. It was a pretty intense and enjoyable couple of hours, the kind of collaboration that I’ve come to expect from my awesome colleagues.&lt;br /&gt;
&lt;br /&gt;
What we eventually hit on was using attribute inheritance in correspondence with our view model so that we would basically have a different analytics attribute for each base model type. This attribute would use the view model data available in OnActionExecuted to complete the population of the analytics data.&lt;br /&gt;
&lt;br /&gt;
The convention is that you only apply the attribute to an action whose model is compatible with the model addressed by the attribute.&amp;nbsp; The attribute inherits the base behavior described above, but then uses its unique knowledge of the view model type to extract the rest of the data.&amp;nbsp; This allows us to put the code that would have been in the action into the attribute instead keeping our action code clean and localizing the analytics code within a few attributes.&lt;br /&gt;
&lt;br /&gt;
Another approach, if the number of models you need to support is large, might use a factory within a common attribute to find and execute a model-specific strategy within OnActionExecuted. For us the number of models is low and inheritance was simpler and easier to comprehend.&lt;br /&gt;
&lt;br /&gt;
There were a number of other problems specific to the customer’s domain that Jesse had to work through and our final solution differs in some respects from what I’ve described, but using attributes to attack analytics seems like a winning choice. Our code is cleaner and more focused, easier to understand, and much more extensible.</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/5525235145983199236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2012/08/analytics-are-aspect.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/5525235145983199236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/5525235145983199236'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2012/08/analytics-are-aspect.html' title='Analytics are an aspect'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9200551703084243537.post-4986709238255810554</id><published>2012-05-22T10:50:00.001-05:00</published><updated>2012-05-22T10:50:45.221-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="AutoMapper"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>Mapping a single property to a complex model</title><content type='html'>I ran into a situation recently where I wanted to flatten several different objects into a single model that would be delivered via JSON to the client code. The tool I&#39;m using as the basis for this is &lt;a href=&quot;http://automapper.org/&quot; target=&quot;_blank&quot;&gt;AutoMapper&lt;/a&gt;.; I found a very useful &lt;a href=&quot;http://consultingblogs.emc.com/owainwragg/archive/2010/12/22/automapper-mapping-from-multiple-objects.aspx&quot; target=&quot;_blank&quot;&gt;post&lt;/a&gt; from &lt;a href=&quot;http://blog.endjin.com/author/owain-wragg/&quot; target=&quot;_blank&quot;&gt;Owain Wragg&lt;/a&gt; that I used as the basis for mapping the various object components onto the single model.&lt;br /&gt;
&lt;br /&gt;
The basic idea is that you use the feature in AutoMapper that let’s you map an object onto an existing object rather than create a new one. First, you map one object onto the destination normally, creating the destination object, then apply mappings from each of the other objects onto the newly created destination object. Slick!&lt;br /&gt;
&lt;br /&gt;
One issue that I had was creating the mappings from each of the sub-objects onto the destination. This model has lots of properties, most filled in from the first of the source objects, with each succeeding object filling in just one property on the model. Ignoring all of those properties for each of the source/destination maps was going to make my configuration long and painful to write. Fortunately, I recalled a trick you can use with AutoMapper to make this easy.&lt;br /&gt;
&lt;br /&gt;
First you create a mapping that ignores all members on the destination. Then you create a map that maps just the single property that you are interested in. Voila! you now have a simple map that projects just a single property onto the destination. I created a little helper method for my AutoMapper configuration class to make things easier. I suspect it would be trivial to make it an extension method, but I’m just using it as a static method on my configuration class.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; MapSingleProperty&amp;lt;Source,Destination&amp;gt;( Expression&amp;lt;Func&amp;lt;Destination,&lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt;&amp;gt;&amp;gt; selector, Action&amp;lt;IMemberConfigurationExpression&amp;lt;Source&amp;gt;&amp;gt; mapping )
{
    Mapper.CreateMap&amp;lt;Source,Destination&amp;gt;()
          .ForAllMembers(opt =&amp;gt; opt.Ignore());
    Mapper.CreateMap&amp;lt;Source,Destination&amp;gt;()
          .ForMember(selector,mapping);
}&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; it’s important to do the ignore first so that the mapping for the single property replaces the ignore mapping rather than the other way around.</content><link rel='replies' type='application/atom+xml' href='http://farm-fresh-code.blogspot.com/feeds/4986709238255810554/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://farm-fresh-code.blogspot.com/2012/05/mapping-single-property-to-complex.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/4986709238255810554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9200551703084243537/posts/default/4986709238255810554'/><link rel='alternate' type='text/html' href='http://farm-fresh-code.blogspot.com/2012/05/mapping-single-property-to-complex.html' title='Mapping a single property to a complex model'/><author><name>tvanfosson</name><uri>http://www.blogger.com/profile/04716379255368704897</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>