<?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-652174954000901332</id><updated>2020-08-28T14:29:57.782+01:00</updated><category term=".NET"/><category term="Testing"/><category term="Random"/><category term="Me"/><category term="Quality"/><category term="Visual Studio"/><category term="WCF"/><category term="ASP.NET MVC"/><category term="Agility"/><category term="Design"/><category term="MVC"/><category term="Music"/><category term="Reflection"/><category term="Silverlight"/><category term="Architecture"/><category term="Commerce Server"/><category term="Continuous Integration"/><category term="DateTime"/><category term="Getting Real"/><category term="Routing"/><category term="C#"/><category term="Database"/><category term="Dependency Injection"/><category term="NHibernate"/><category term="Ninject"/><category term="Route Constraints"/><category term="SEO"/><category term="Session Management"/><category term="Time Zone"/><category term="Travel"/><category term="UTC"/><category term="Unit of Work"/><category term="Usability"/><category term="WTF"/><category term="Windsor"/><title type='text'>Øyvind Valland&#39;s Babel Lutefisk .net</title><subtitle type='html'>[bey-buhl loo-tuh-fisk] : A distant relative of the Babel Fish. Recognisable by its glassy eyes and incomprehensible jabbering.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default?start-index=26&amp;max-results=25'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>69</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-3312915004143514034</id><published>2014-01-23T20:31:00.000+00:00</published><updated>2014-01-23T20:40:48.553+00:00</updated><title type='text'>MicroSpec</title><content type='html'>In the last two or three years I have been doing a lot of BDD, and I have really enjoyed it. Introducing BDD in a project for my latest client has been particularly rewarding. This company has previously relied heavily on manual regression testing and the majority of its QA staff were not trained sufficiently in development to be able to write their own automated tests. As mentioned this lead to a heavy reliance on manual testing but it also lead to something else: the unit and integration tests that were written by developers were largely ignored by the QAs because they did not understand them. &quot;Not understanding&quot; meant more than that they couldn&#39;t read the test source code and work out what the tests did. The tests were inconsistently named and poorly organised, and the QAs felt that they could not assess whether the appropriate test coverage had been achieved (real coverage, not a percentage of lines covered). This lead to unit and integration tests not being run as part of builds.&lt;br /&gt;&lt;br /&gt;I&#39;ve oversimplified this scenario - there are many reasons other than the QAs&#39; inability to write and understand automated tests that led to this situation. However, the point is that that was the state of affairs - and things needed to be done. The reliance on manual regression testing meant releases were incredibly infrequent, and a full regression test cycle could easily take six weeks. If that&#39;s not madness, I don&#39;t know what is.&lt;br /&gt;&lt;br /&gt;The company had brought in a new head of QA to sort out this mess, and his directive was fairly simple. Automate all tests that can be automated without excessive cost, write all tests as specifications (preferably with a Gherkin-style language and/or SpecFlow), and prefer BDD over TDD for new development work. Following this directive many existing manual regression tests were created as UI automation tests using SpecFlow and Selenium, existing integration and unit tests were cleaned up and made part of the build, and the company as a whole (well, more or less) attempted to embrace the BDD style of specifying test cases.&lt;br /&gt;&lt;br /&gt;However, there was still the problem of new unit and integration tests. Developers across the organisation were used to writing their tests with NUnit and Moq. A typical, contrived, test could look something like:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;[Test]&lt;br /&gt;[ExpectedException(typeof(InvalidOperationException))]&lt;br /&gt;public void ExceptionIfOrderIsNotDispatched()&lt;br /&gt;{&lt;br /&gt;  var order = new Order(){&lt;br /&gt;                           Id= 12345;&lt;br /&gt;                           //... other initialisation&lt;br /&gt;                         };&lt;br /&gt;  var refundAmount = 12.50;&lt;br /&gt;  _orderService = new Mock&lt;IOrderService&gt;();&lt;br /&gt;  _orderService.Setup(x =&amp;gt; x.Retrieve(order.Id)).Returns(order);&lt;br /&gt;&lt;br /&gt;  var billingService = new BillingService(_orderService.Object);&lt;br /&gt;&lt;br /&gt;  //throws because we haven&#39;t dispatched the order yet&lt;br /&gt;  billingService.Refund(order.Id, refundAmount);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This test is simple and if you&#39;re a developer you can probably read it just fine. But if you&#39;re &lt;i&gt;not&lt;/i&gt; a developer this is can be hard to understand. What are we testing, exactly? There is a comment in the test that says the order hasn&#39;t been dispatched and that&#39;s why an exception will be thrown - but what if the comment wasn&#39;t there? Even if you &lt;i&gt;are&lt;/i&gt;&amp;nbsp;a developer and you come across this test you&#39;re likely to have to go digging to really understand what the test is all about. Whether or not you think this style of writing tests is problematic is a matter of taste and preference, but what we realised in our project was that the non-developer QA who wanted to assess whether the right level of test coverage had been achieved would often be completely at a loss as to what had been tested.&lt;br /&gt;&lt;br /&gt;In order to address this particular problem we decided that we should write all our unit and integration tests as specifications. We decided that the test we&#39;ve already discussed should be written like this:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;  &lt;br /&gt;  Given I have an order&lt;br /&gt;    And the order has not yet been dispatched&lt;br /&gt;  When I try to refund an amount against the order&lt;br /&gt;  Then an InvalidOperationException is thrown&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is a test that anybody can read and understand, regardless of technical ability, so we decided we&#39;d write all our tests in this way so that anyone could look at any test, be it UI Automation test, database integration test or unit test and easily understand not only what it does, what it tests and why it failed (if that were the case).&lt;br /&gt;&lt;br /&gt;The first, and rather obvious, choice of tooling for definig the tests was SpecFlow. However, we soon realised that it wasn&#39;t a good choice for this organisation. There was (not surprisingly) some resistance to having to use a new tool from the developers - why couldn&#39;t they just keep using NUnit like they had? Also, we quickly realised that although non-technical QAs now certainly &lt;i&gt;could&lt;/i&gt;&amp;nbsp;help define unit tests using Gherkin they typically didn&#39;t. So we decided to take matters in our own hands and create our own tiny framework, one that would give the best of both worlds: Specification style tests written using nothing but NUnit and Moq. I&#39;ve called this framework MicroSpec.&lt;br /&gt;&lt;br /&gt;MicroSpec is essentially one code file (I&#39;ve taken a leaf out of &lt;a href=&quot;https://code.google.com/p/dapper-dot-net/&quot; target=&quot;_blank&quot;&gt;Dapper&#39;s&lt;/a&gt; book) containing a single class, the Specification class, which implements four interfaces. The Specification class is an abstract class which executes your tests and prints the specification to the console as the tests run. You write tests by specifying each step in the test as a separate method and passing these steps as delegates to the Specification class&#39; Given-When-Then methods. The test we&#39;ve already looked at, above, could be written like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;[Test]&lt;br /&gt;public void ThrowsExceptionIfIssuingRefundBeforeOrderIsDispatched()&lt;br /&gt;{&lt;br /&gt;  Given(i_have_an_order).&lt;br /&gt;  And(the_order_has_not_yet_been_dispatched).&lt;br /&gt;  When(i_try_to_refund_an_amount_against_the_order).&lt;br /&gt;  ThenAn&lt;InvalidOperationException&gt;().IsThrown();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here we have three methods which define the steps in our test definition. They are all called by the specification class:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;pre&gt;i_have_an_order&lt;/pre&gt;creates a new order for use by our test&lt;/li&gt;&lt;li&gt;&lt;pre&gt;the_order_has_not_yet_been_dispatched&lt;/pre&gt;ensures that the order created in the previous step has not been dispatched. This might execute some logic on the order or just assert that the state of the order is correct.&lt;/li&gt;&lt;li&gt;&lt;pre&gt;i_try_to_refund_an_amount_against_the_order&lt;/pre&gt;would issue a refund against the order.&lt;/li&gt;&lt;/ul&gt;The last step in the test is a call to ThenAn&lt;t&gt; which is a method that&#39;s used to capture expected exceptions. Chaining ThenAn&lt;t&gt; (or it&#39;s brother ThenA&lt;t&gt; for those who care about grammar) with IsThrown() asserts that a specific exceptions has been thrown during the course of the test (if you want to make sure an exception was _not_ thrown, you&#39;d end the chain with IsNotThrown() instead).&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;br /&gt;&lt;br /&gt;As the test runs the Specification class creates console output before each step is executed. I&#39;ll repeat the output of this test here so you don&#39;t have to scroll:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;  Given I have an order&lt;br /&gt;    And the order has not yet been dispatched&lt;br /&gt;  When I try to refund an amount against the order&lt;br /&gt;  Then an InvalidOperationException is thrown&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As you can see, the console output takes the names of the delegates/steps and prefixes them with the type of step: &quot;Given&quot;, &quot;When&quot;, &quot;Then&quot;, &quot;And&quot;, &quot;Then an&quot;, &quot;Then a&quot;, &quot;is thrown&quot; or &quot;is not thrown&quot;. But the console output does not have to be constrained to just the name of the steps within the test. You can also include test parameters by following the following naming conventions:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;integers surrounded by underscores, e.g. _0_, are replaced by the value of the corresponding parameter passed to the step.&lt;/li&gt;&lt;li&gt;integers preceded by the letter &quot;g&quot; and surrounded by underscores, e.g. &quot;_g0_&quot;, are replaced by the name of the corresponding generic parameter defined by the step.&lt;/li&gt;&lt;/ul&gt;To illustrate, imagine that the value of the refund issued in the above test matters. You could then rewrite the test like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;[Test]&lt;br /&gt;public void ThrowsExceptionIfIssuingRefundBeforeOrderIsDispatched()&lt;br /&gt;{&lt;br /&gt;  var refundAmount = 20;&lt;br /&gt;  var currencySymbol = &quot;GBP&quot;;&lt;br /&gt;&lt;br /&gt;  Given(i_have_an_order).&lt;br /&gt;  And(the_order_has_not_yet_been_dispatched).&lt;br /&gt;  When(i_try_to_refund_0__1_against_the_order, refundAmount, currencySymbol).&lt;br /&gt;  ThenAn&lt;InvalidOperationException&gt;().IsThrown();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When run the output of the test would be:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;  Given I have an order&lt;br /&gt;    And the order has not yet been dispatched&lt;br /&gt;  When I try to refund 20 GBP against the order&lt;br /&gt;  Then an InvalidOperationException is thrown&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Writing unit tests in this manner takes a little getting used to, and I find that it generally takes a little longer to complete the first couple of tests than when following a more traditional approach. That&#39;s because you&#39;ve got a little more &quot;infrastructure&quot; to create in order for your tests to run. Managing state between test runs can also be a little trickier sometimes. But the tests themselves become infinitely more understandable and readable than tests written in a traditional way, and I think that the extra effort you have to put into defining your steps clearly in English language not only helps make your tests better but also aids in designing the software you&#39;re building. Describing the pictures you have in your mind with words while you&#39;re in the early stages of coding up a solution is a good way of vetting your design ideas.&lt;br /&gt;&lt;br /&gt;Anyway - MicroSpec works for me, and it&#39;s bridged the gap between non-technical QAs who want to read and understand low-level (tests) and the developers that write them. It&#39;s the way I currently like to write my unit tests. If you want to give it a try, you can &lt;a href=&quot;https://bitbucket.com/peppershrimp/microspec&quot; target=&quot;_blank&quot;&gt;download it from BitBucket&lt;/a&gt;. Any thoughts and comments are most welcome.</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/3312915004143514034/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=3312915004143514034' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/3312915004143514034'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/3312915004143514034'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2014/01/microspec.html' title='MicroSpec'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-5480884519089796823</id><published>2013-01-03T16:55:00.002+00:00</published><updated>2013-01-03T16:55:36.601+00:00</updated><title type='text'>A tidy way to organise your JavaScript</title><content type='html'>Last year I was lucky enough to work on several projects with some very good UI developers. Doing so enabled to greatly improve my own skills in that area, and one of the biggest &#39;take-aways&#39; from these projects was the way in which these guys preferred to manage the JavaScript in a project. In this post I will outline how they did it, and why they did it this way.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;Note: &lt;/b&gt;I really like this approach because it&#39;s solved (and neatly so) a problem I never seemed to sort out in a satisfactory manner on my own. I am sure there are many other good ways of doing this - I&#39;m just particularly fond of this solution. I welcome discussion on the matter!&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;The basic idea behind how the JS should be organised can probably be summed up in three simple points:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Everything is namespaced (and thus organised accordingly).&lt;/li&gt;&lt;li&gt;Every page that requires JS has a single &#39;page class&#39; that creates and initialises JS components that work on that particular page. A &#39;page class&#39; should not do anything except initialisation.&lt;/li&gt;&lt;li&gt;All JS code that provides functionality to a page should is organised into logical components.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;I&#39;ll address each bullet point in order, but before doing so let&#39;s have a quick way at how the JS files are organised in the web project (or on disk, for that matter). Note that the code examples and screen shots are from a ASP.NET MVC4 project in VS2012.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-al8RXjnOk9I/UOWhTK0OAQI/AAAAAAAAAZM/MiJdc6YnHiQ/s1600/js_folder_structure.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; height=&quot;400&quot; src=&quot;http://1.bp.blogspot.com/-al8RXjnOk9I/UOWhTK0OAQI/AAAAAAAAAZM/MiJdc6YnHiQ/s400/js_folder_structure.png&quot; width=&quot;220&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;As you can see from the picture on the right I have modified the default project structure somewhat. In the &quot;Content&quot; folder I have created a &quot;Scripts&quot; folder (with multiple sub-folders) and also a &quot;Styles&quot; folder. In this post I&#39;ll only talk about the &quot;~/Content/Scripts/MyApp&quot; folder and its files/sub-folders. I&#39;ll mention here, though, that the &quot;~/Content/Styles&quot; folder contains the &quot;site.css&quot; stylesheet and the &quot;themes&quot; folder from the original project. The &quot;~/Content/Scripts/Plugins&quot; folder contains all the scripts that were originally placed in the &quot;~/Scripts/&quot; folder, and the &quot;~/Content/Scripts/Jasmine/&quot; folder will hold all Jasmine files and tests.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, back to the bullet points. We&#39;ll address them in order, starting with:&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Namespaces&lt;/h4&gt;&lt;div&gt;The &quot;~/Content/Scripts/MyApp&quot; folder should be named in accordance with whatever your application is called. Inside this folder, place a single JS file named in accordance with whatever the root namespace of you application&#39;s JS should be. I usually use the application name as the root namespace, hence I name the root namespace file MyApp.js.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Inside this file I simply declare the root namespace like this:&lt;/div&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;  &lt;br /&gt;  var MyApp = {};&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;You&#39;ll notice that inside the &quot;~/Content/Scripts/MyApp/&quot; folder there is also a &quot;Pages&quot; folder. This is the folder that will hold all the JS files that define the previously mentioned page classes. The &quot;Pages&quot; folder has two files: MyApp.Pages.js, which defines the MyApp.Pages namespace...&lt;/div&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;  &lt;br /&gt;  MyApp.Pages = {};&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;... and also MyApp.Pages.Home.js, which defines the &quot;Home&quot; page class. We will get onto the details of this particular file in a second.&lt;br /&gt;&lt;br /&gt;Although we&#39;ve only talked about two folders and three files, I&#39;ve hinted at a pattern with regard to namespaces. Every folder under &quot;~/Scripts/Content/MyApp/&quot; represents and is named in accordance with a namespace. That namespace is &lt;i&gt;defined&lt;/i&gt;&amp;nbsp;in a JS file named exactly the same as the full namespace, e.g. MyApp.Pages.js or MyApp.MappingComponents.js.&lt;br /&gt;&lt;br /&gt;In this example there are only two namespaces, and that&#39;s fine to start with. I keep all components in the root namespace unless some are completely page specific (thus not really reusable) or unless there are too many of them so that it becomes useful to group them.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Page classes&lt;/h4&gt;&lt;/div&gt;&lt;div&gt;All page classes are defined under the &quot;MyApp.Pages&quot; namespace. The purpose of a page class is to create and initialise all JS (components) required by a specific page in your web application. In this example we have the MyApp.Pages.Home class. Let&#39;s take a closer look:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;  $(function () {&lt;br /&gt;    MyApp.Pages.Home = new function () {&lt;br /&gt;      this.CountryMap = new MyApp.GoogleMap($(&#39;#map_canvas&#39;)[0]);&lt;br /&gt;      this.CountryMap.init(66.196009, 14.143799, 4);&lt;br /&gt;    }&lt;br /&gt;  });&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;All this page class does is create a GoogleMap component, and initialise it. On creation the component is passed a reference to the div that we want to render the map within, and then it is initialised by calling the &lt;i&gt;init&lt;/i&gt;&amp;nbsp;method of the component and passing in the latitude, longitude, and map zoom level.&lt;br /&gt;&lt;br /&gt;This is a contrived example, so I&#39;ve hardcoded the initialisation of the map instance. In a &#39;real world&#39; scenario you&#39;d probably have your page class either read the lat/lng from hidden form fields on the page or perhaps request the lat/lng by making an ajax call. The point is, beyond doing the necessary work for creating and initialising &lt;i&gt;components&lt;/i&gt;, the page class is pretty simple.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Components&lt;/h4&gt;&lt;div&gt;All JavaScript for a page should be encapsulated in (reusable) components, and each component should be defined in its own, separate file. There are two reasons for this: It makes your JS more manageable because each component is defined in one place and has one purpose. It also makes your JS easier to test, because each component is discrete. The latter point is still subject to how you choose to build your components, though, and I&#39;m not going to go into testing of JS here.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let&#39;s have a quick look at the GoogleMap component that&#39;s used by the Home page class:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;  MyApp.GoogleMap = function (canvas) {&lt;br /&gt;    this.canvas = canvas;&lt;br /&gt;  };&lt;br /&gt;&lt;br /&gt;  MyApp.GoogleMap.prototype.generateMap = function (lat, lng, zoomLevel) {&lt;br /&gt;    var canvasElement = this.canvas[0];&lt;br /&gt;    var mapOptions = {&lt;br /&gt;        center: new google.maps.LatLng(lat, lng),&lt;br /&gt;        zoom: zoomLevel,&lt;br /&gt;        mapTypeId: google.maps.MapTypeId.ROADMAP,&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    this.map = new google.maps.Map(canvasElement, mapOptions);&lt;br /&gt;  };&lt;br /&gt;&lt;br /&gt;  MyApp.GoogleMap.prototype.init = function (lat, lng, zoomLevel) {&lt;br /&gt;    this.generateMap(lat, lng, zoomLevel);&lt;br /&gt;  };&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;This is a very simple component that creates a Google map instance on a div in your HTML markup. As you can see, when an instance of this component is created you pass it a reference to the div that should be used as the canvas for the map. This reference is then stored so that when the init() method is called the map can be drawn within the given div.&lt;/div&gt;&lt;br /&gt;&lt;h4&gt;Putting it together&lt;/h4&gt;&lt;div&gt;In order to make all of this work we just have to do the following:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Add a reference to the Google Maps API within the &lt;head&gt; tag of _Layout.cshtml&lt;/head&gt;&lt;/li&gt;&lt;li&gt;Add references to &quot;~/Content/Scripts/MyApp/MyApp.js&quot; and &quot;~/Content/Scripts/MyApp/Pages/MyApp.Pages.js&quot; within _Layout.cshtml&lt;/li&gt;&lt;li&gt;Add references to &quot;~/Content/Scripts/MyApp/MyApp.GoogleMap.js&quot; and &quot;~/Content/Scripts/MyApp/Pages/MyApp.Pages.Home.js&quot; within the &quot;~/Views/Home/Index.cshtml&quot; view.&lt;/li&gt;&lt;li&gt;Add a div with the id &quot;map_canvas&quot;&amp;nbsp;within the &quot;~/Views/Home/Index.cshtml&quot; view. Oh - and you should style it, too, to the desired size.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;With all this in place, the home page should look something like this:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://3.bp.blogspot.com/-2_uOYHb_Abg/UOW1xRYdvTI/AAAAAAAAAZk/rEA_QBTbCKE/s1600/js_folder_structure_homepage_view.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;394&quot; src=&quot;http://3.bp.blogspot.com/-2_uOYHb_Abg/UOW1xRYdvTI/AAAAAAAAAZk/rEA_QBTbCKE/s640/js_folder_structure_homepage_view.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;h4&gt;Points to note&lt;/h4&gt;&lt;/div&gt;&lt;div&gt;While I really like this solution, there are a couple of things to beware of before you start using it yourself. The most important thing to realise is that as your site grows, so will the number of JavaScript files. If you reference each file separately the web browser will potentially have to make a lot of requests in order to render a single page, and this is bad for performance. Therefore you should utilise bundling so that multiple files can be combined into a single downloadable unit.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;While bundling is really helpful for the above scenario, you should also exercise some restraint when defining these. Because of the number of JS files you might have in a large project it &lt;i&gt;can&lt;/i&gt; be tempting to &quot;bundle everything&quot; into one big, eh, bundle and reference that everywhere. That&#39;s ultimately counter productive because the web browser will have to download more than what&#39;s required for a single page, and it will probably lead to a lax attitude towards the boundaries that you&#39;ve defined within your JS, too.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/5480884519089796823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=5480884519089796823' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/5480884519089796823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/5480884519089796823'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2013/01/a-tidy-way-to-organise-your-javascript.html' title='A tidy way to organise your JavaScript'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-al8RXjnOk9I/UOWhTK0OAQI/AAAAAAAAAZM/MiJdc6YnHiQ/s72-c/js_folder_structure.png" height="72" width="72"/><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-2797374453102274427</id><published>2011-11-07T22:47:00.007+00:00</published><updated>2011-11-07T23:20:58.577+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC"/><category scheme="http://www.blogger.com/atom/ns#" term="Routing"/><category scheme="http://www.blogger.com/atom/ns#" term="SEO"/><title type='text'>MVC Lower-case URLs</title><content type='html'>SEO guidelines usually recommend that a site&#39;s URLs should be kept in all lower-case. The reason for this is that search engines and web servers alike (IIS is a notable exception) will treat two differently cased URLs as two different resources. While the host name of a URL is case insensitive (i.e. there&#39;s no difference between http://www.mysite.com and http://www.MySite.com) the resource path is not. Therefore http://www.mysite.com/home and http://www.mysite.com/Home are considered different resources.&lt;br /&gt;&lt;br /&gt;While this might not make much sense semantically, consider this: &lt;a href=&quot;http://w3techs.com/technologies/overview/web_server/all&quot;&gt;The world&#39;s most widely used web server&lt;/a&gt;, Apache, treats URLs as case sensitive. Therefore the above URLs do, in fact, represent two different pages. As such, search engines treat these two URLs as different pages, too - and if your website doesn&#39;t care about URL casing you might end up with a split index for your pages.&lt;br /&gt;&lt;br /&gt;So - how do we ensure that your website generates only lower-case URLs? With ASP.NET MVC this is easy. All you need is:&lt;ul&gt;&lt;li&gt;A LowercaseRoute class&lt;/li&gt;&lt;li&gt;An extension method for RouteCollection&lt;/li&gt;&lt;li&gt;An extension method for AreaRegistrationContext&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;And yes - the solution I&#39;m about to detail will work with MVC Areas.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The LowercaseRoute class extends the Route class and basically lets that class do all the work. LowercaseRoute just ensures that the host and path portions of he URL are turned to lower-case while the querystring portion is left alone:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;internal class LowercaseRoute : Route&lt;br /&gt;{&lt;br /&gt;    public LowercaseRoute(string url, IRouteHandler routeHandler)&lt;br /&gt;            : base(url, routeHandler){}&lt;br /&gt;&lt;br /&gt;    public LowercaseRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler)&lt;br /&gt;         : base(url, defaults, routeHandler){}&lt;br /&gt;&lt;br /&gt;    public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler)&lt;br /&gt;            : base(url, defaults, constraints, routeHandler){}&lt;br /&gt;&lt;br /&gt;    public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler)&lt;br /&gt;            : base(url, defaults, constraints, dataTokens, routeHandler){}&lt;br /&gt;&lt;br /&gt;    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)&lt;br /&gt;    {&lt;br /&gt;        var path = base.GetVirtualPath(requestContext, values);&lt;br /&gt;&lt;br /&gt;        if (path != null)&lt;br /&gt;        {&lt;br /&gt;            var virtualPath = path.VirtualPath;&lt;br /&gt;&lt;br /&gt;            if (virtualPath.LastIndexOf(&quot;?&quot;) &gt; 0)&lt;br /&gt;            {&lt;br /&gt;                var leftPart = virtualPath.Substring(0, virtualPath.LastIndexOf(&quot;?&quot;)).ToLowerInvariant();&lt;br /&gt;                var queryPart = virtualPath.Substring(virtualPath.LastIndexOf(&quot;?&quot;));&lt;br /&gt;                path.VirtualPath = leftPart + queryPart;&lt;br /&gt;            }&lt;br /&gt;            else&lt;br /&gt;                path.VirtualPath = path.VirtualPath.ToLowerInvariant();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return path;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The RouteCollection extension method creates an instance of LowercaseRoute and adds it to the route collection:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;public static Route MapRouteLowercase(this RouteCollection routes, string name, string url, object defaults)&lt;br /&gt;{&lt;br /&gt;    if (routes == null)&lt;br /&gt;        throw new ArgumentNullException(&quot;routes&quot;);&lt;br /&gt;&lt;br /&gt;    if (url == null)&lt;br /&gt;        throw new ArgumentNullException(&quot;url&quot;);&lt;br /&gt;&lt;br /&gt;    var route = new LowercaseRoute(url, new MvcRouteHandler())&lt;br /&gt;                    {&lt;br /&gt;                        Defaults = new RouteValueDictionary(defaults)&lt;br /&gt;                    };&lt;br /&gt;&lt;br /&gt;    routes.Add(name, route);&lt;br /&gt;    return route;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The AreaRegistrationContext extension method calls the MapRouteLowercase extension method on RouteCollection and also adds the current context&#39;s AreaName property to the route&#39;s DataTokens collection. This second step is crucial for areas to work:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;public static Route MapRouteLowercase(this AreaRegistrationContext context, string name, string url, object defaults)&lt;br /&gt;{&lt;br /&gt;    var route = context.Routes.MapRouteLowercase(name, url, defaults, constraints, namespaces);&lt;br /&gt;&lt;br /&gt;    route.DataTokens[&quot;area&quot;] = context.AreaName;&lt;br /&gt;    return route;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And that&#39;s all you really need. Of course, you may want to add more extension methods of your own so that you can add route constraints or any other data that your route handler may need (such as namespace differentiators). But I&#39;ll leave that for you to flesh out on your own. Happy coding!</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/2797374453102274427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=2797374453102274427' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/2797374453102274427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/2797374453102274427'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2011/11/mvc-lower-case-urls.html' title='MVC Lower-case URLs'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-8734739809477534274</id><published>2011-11-01T12:48:00.005+00:00</published><updated>2011-11-07T21:35:56.870+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC"/><category scheme="http://www.blogger.com/atom/ns#" term="Route Constraints"/><category scheme="http://www.blogger.com/atom/ns#" term="Routing"/><title type='text'>Route Constraints: Working with conflicting routes in MVC</title><content type='html'>Routing is one of the things in the MVC framework that seems to just &#39;get me&#39; every once in a while. Routing isn&#39;t that hard - it&#39;s pretty straight forward stuff. Routing is something you should, ideally, set up once - and then forget about. In order to do this, though, you need to have a plan up front - and you don&#39;t always have that (personally I think it&#39;s best if you&#39;ve got a site map and a URL schema worked out before you start). If you add routes as you need them you can end up with more routes than you need and route conflicts that you didn&#39;t foresee.&lt;br /&gt;&lt;br /&gt;This isn&#39;t intended as a post about MVC routing in general. Rather I wanted to post about a little piece of work I had to do in order to make use of two routes that conflict with one another. I think these routes highlight the most common problem people have when they&#39;re getting to grips with MVC routes; your URL is matched by the wrong route entry.&lt;br /&gt;&lt;br /&gt;I like to keep things simple, and I don&#39;t like making extra work for myself. As such I like the default route that any Visual Studio MVC project comes set up with:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;routes.MapRoute(string.Empty, &quot;{controller}/{action}/{id}&quot;,&lt;br /&gt;  new { controller = &quot;Home&quot;, action = &quot;Index&quot;, id = UrlParameter.Optional });&lt;br /&gt;&lt;/pre&gt;  &lt;br /&gt;This route entry is simple to understand and you can build large applications based entirely on this single route entry. Of course, you may want to add some &quot;pretty&quot; routes as well such as &quot;/login&quot; or &quot;/signup&quot; - but that single route is really all you need. That is, until you decide that not all your URLs should be on the form &quot;{controller}/{action}/{id}.&quot;&lt;br /&gt;&lt;br /&gt;In my case, I also needed a route like this:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;routes.MapRoute(string.Empty, &quot;{controller}/{id}&quot;,&lt;br /&gt;  new { controller = &quot;Clubs&quot;, action = &quot;Index&quot;, id = UrlParameter.Optional });&lt;br /&gt;&lt;/pre&gt;  &lt;br /&gt;This second route is important to my application because it&#39;s used to display certain entities by their unique identifier. Such entities can be a member of the site, a club, or a store. Example URLs are:&lt;br /&gt;&lt;br /&gt;http://mywebsite.com/members/oyvind&lt;br /&gt;http://mywebsite.com/stores/oyvindsmegamart&lt;br /&gt;http://mywebsite.com/clubs/oyvindsgreatbigfanclub&lt;br /&gt;&lt;br /&gt;As you can tell from the example URLs, several controllers can be mapped by this route and, if they are, the route should always map to the &quot;index&quot; action method and pass in the &quot;id&quot; parameter. But, if you add these routes to your application, you&#39;ll run into trouble because they conflict with each other. Let&#39;s look at why.&lt;br /&gt;&lt;br /&gt;An incoming URL will be matched by one route and one route only. Routes are examined one by one and the first match is the one that will be used. This means that the order in which we add routes is important. We always want our most specific routes to be listed first. Let&#39;s apply this principle to our two routes:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;routes.MapRoute(string.Empty, &quot;{controller}/{id}&quot;,&lt;br /&gt;  new { controller = &quot;Clubs&quot;, action = &quot;Index&quot;, id = UrlParameter.Optional });&lt;br /&gt;routes.MapRoute(string.Empty, &quot;{controller}/{action}/{id}&quot;,&lt;br /&gt;  new { controller = &quot;Home&quot;, action = &quot;Index&quot;, id = UrlParameter.Optional });&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here I&#39;ve added the &quot;{controller}/{id}&quot; route first because I feel this is the more specific of the two routes. Now let&#39;s look at a sample URL:&lt;br /&gt;&lt;br /&gt;http://mywebsite.com/members/oyvind&lt;br /&gt;&lt;br /&gt;If we break this URL down you&#39;ll see that the &quot;/members&quot; section of the URL will map to the &quot;{controller}&quot; portion of both routes. Also, the &quot;/oyvind&quot; section of the URL will map to the &quot;{id}&quot; portion of the first route. Happy days! We have a match! It looks like our two route entries might work after all.&lt;br /&gt;&lt;br /&gt;But not so fast. What about this URL?&lt;br /&gt;&lt;br /&gt;http://mywebsite.com/account/changepassword&lt;br /&gt;&lt;br /&gt;This URL should look familiar to you as it&#39;s more of a traditional MVC route; in fact, it&#39;s a classic default route for any standard MVC project. But will this work with our two route entries? The &quot;/account&quot; section of the URL will map to the &quot;{controller}&quot; portion of both routes. The &quot;/changepassword&quot; section of the URL will map to both the &quot;{id}&quot; portion of the first route, and the &quot;{action}&quot; portion of the second route. However, because the first match wins, the first route is chosen and the request will end up being directed to the Index action method on the AccountController class, with an id parameter of &quot;changepassword&quot;... this isn&#39;t what we intended.&lt;br /&gt;&lt;br /&gt;What happens if we change the order of the routes?&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;routes.MapRoute(string.Empty, &quot;{controller}/{action}/{id}&quot;,&lt;br /&gt;  new { controller = &quot;Home&quot;, action = &quot;Index&quot;, id = UrlParameter.Optional });&lt;br /&gt;routes.MapRoute(string.Empty, &quot;{controller}/{id}&quot;,&lt;br /&gt;  new { controller = &quot;Clubs&quot;, action = &quot;Index&quot;, id = UrlParameter.Optional });&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Let&#39;s look at the last URL from the previous example first:&lt;br /&gt;&lt;br /&gt;http://mywebsite.com/account/changepassword&lt;br /&gt;&lt;br /&gt;The &quot;/account&quot; section of the URL will map to the &quot;{controller}&quot; portion of both routes. The &quot;/changepassword&quot; section of the URL will map to both the &quot;{action}&quot; portion of the first route, and the &quot;{id}&quot; portion of the second route. In this case our first route will be selected - and the request will be directed to the ChangePassword action method on the AccountController (with an empty id). This is the desired result for this URL. But what about this URL?&lt;br /&gt;&lt;br /&gt;http://mywebsite.com/members/oyvind&lt;br /&gt;&lt;br /&gt;The &quot;/members&quot; section of the URL will map to the &quot;{controller}&quot; portion of both routes. The &quot;/oyvind&quot; sectin of the URL will map to the &quot;{action}&quot; portion of the first route, and the &quot;{id}&quot; portion of the second route. Because of the order of precedence, the first route will be selected and our request will be directed to the Oyvind action on the MembersController, with an empty id. Most likely we&#39;ll end up with a &quot;404 - Not Found&quot; because I doubt very much you&#39;ll have an action called Oyvind on any of your controllers.&lt;br /&gt;&lt;br /&gt;I &lt;span style=&quot;font-style:italic;&quot;&gt;need&lt;/span&gt; both routes to work, but they clearly conflict with each other and changing the order of the routes doesn&#39;t actually help. What can I do? Somehow I need to help the MVC framework understand when to pick one route over the other. Thankfully there&#39;s a built-in mechanism we can leverage to help us: the route &lt;i&gt;constraint&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;When you add a route to the route table you can specify that this route has certain constraints. A constraint applies to a portion of the route (for example the &quot;{id}&quot; portion) and can set out that this portion has to match certain values, be of a certain format, or exclude specific values. When defining routes you pass the constraints as a third parameter to the MapRoute method:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;routes.MapRoute(string.Empty, &quot;{controller}/{action}/{id}&quot;,&lt;br /&gt;  new { controller = &quot;Home&quot;, action = &quot;Index&quot;, id = UrlParameter.Optional },&lt;br /&gt;  new { action = &quot;MySpecialAction&quot;});&lt;br /&gt;&lt;/pre&gt;  &lt;br /&gt;In this contrived example I&#39;ve specified a route using the standard/default route pattern, but I&#39;ve specified a constraint for the &quot;{action}&quot; portion of the route. The constraint states that unless &quot;{action}&quot; equals &quot;MySpecialAction&quot; the route will not be matched. This route constraint is actually a regular expression constraint, so you if you want to allow &quot;{action}&quot; to include not only &quot;MySpecialAction&quot; but also &quot;YourSpecialAction&quot; you can alter the route entry as follows:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;routes.MapRoute(string.Empty, &quot;{controller}/{action}/{id}&quot;,&lt;br /&gt;  new { controller = &quot;Home&quot;, action = &quot;Index&quot;, id = UrlParameter.Optional },&lt;br /&gt;  new { action = &quot;MySpecialAction|YourSpecialAction&quot;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can read more about route constraints here (http://www.asp.net/mvc/tutorials/creating-a-route-constraint-cs) as I&#39;m not going to dwell on the specifics here. Rather, I want to get on with the problem at hand. Let&#39;s break it down a little:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I want to use the default route &quot;{controller}/{action}/{id}&quot; as much as possible. This is the route I want to base my whole site on.&lt;/li&gt;&lt;li&gt;In some special cases I want the route &quot;{controller}/{id}&quot; to take precedence. At the moment I know that I want this route to take precedence for the MembersController, the ShopsController, and the ClubsController.&lt;/li&gt;&lt;li&gt;I want to be able to define action methods other than Index on the MembersController, ShopsController, and ClubsController - and I want these actions to be matched by the default route.&lt;/li&gt;&lt;/ul&gt;  The problem we encountered with the routes in their raw, unconstrained, form is that the &quot;{id}&quot; portion of a route will happily match the &quot;{action}&quot; portion of the other route, and vice versa. Since we add the most specific route first&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;routes.MapRoute(string.Empty, &quot;{controller}/{id}&quot;,&lt;br /&gt;              new { controller = &quot;Clubs&quot;, action = &quot;Index&quot;, id = UrlParameter.Optional });&lt;br /&gt;&lt;/pre&gt;  &lt;br /&gt;we need to make sure that the &quot;{id}&quot; parameter does not match any action methods on the controller. Also, we don&#39;t want this route to apply to all controllers, so we need to constrain the &quot;{controller}&quot; portion of the route to the desired controllers. Let&#39;s start with the controller constraint first. We want this route to only apply to the ClubsController, ShopsController, and MembersController:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;routes.MapRoute(string.Empty, &quot;{controller}/{id}&quot;,&lt;br /&gt;  new { controller = &quot;Clubs&quot;, action = &quot;Index&quot;, id = UrlParameter.Optional },&lt;br /&gt;  new { controller = &quot;Clubs|Members|Shops&quot;});&lt;br /&gt;&lt;/pre&gt;  &lt;br /&gt;That&#39;s all we need to do.&lt;br /&gt;&lt;br /&gt;The other constraint, however, is a little bit more involved. The route should &lt;i&gt;not&lt;/i&gt; be matched if the &quot;{id}&quot; portion of the URL matches &lt;i&gt;any&lt;/i&gt; of the action methods on any of the controllers that this route applies to. We can do this by applying another regex constraint which contains the names of all the action methods on these controllers:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;routes.MapRoute(string.Empty, &quot;{controller}/{id}&quot;,&lt;br /&gt;  new { controller = &quot;Clubs&quot;, action = &quot;Index&quot;, id = UrlParameter.Optional },&lt;br /&gt;  new&lt;br /&gt;{&lt;br /&gt;   controller = &quot;Clubs|Members|Shops&quot;,&lt;br /&gt;   id = &quot;ClubMembers|Photos|News|Deals|Staff|Wall|About|OpeningHours|Info|Friends&quot;&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;  &lt;br /&gt;The above example is contrived - but it attempts to highlight a problem with the approach. Not only will this list of action names grow very quickly, you will also have to remember to add action names to this list whenever you add an action on any of the controllers (or modify the list if you change the name of any of the action methods). This approach will work, but it&#39;s not a very maintainable solution.&lt;br /&gt;&lt;br /&gt;A better approach would be to use a &lt;i&gt;custom route constraint&lt;/i&gt;. A custom route constraint is a class which implements the IRouteConstraint interface. This interface defines a method called Match:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The job of the custom route constraint is to decide if a given route parameter is valid for the given route. We want to check a single parameter, &quot;id&quot; against a potentially large list of values. To this end, I&#39;ve created a ValuesConstraint class:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;public class ValuesConstraint : IRouteConstraint&lt;br /&gt;{&lt;br /&gt;  private readonly bool _include;&lt;br /&gt;  private readonly string[] _values;&lt;br /&gt;&lt;br /&gt;  public ValuesConstraint(params string[] values) : this(true, values){}&lt;br /&gt;  public ValuesConstraint(bool include, params string[] values)&lt;br /&gt;  {&lt;br /&gt;      _include = include;&lt;br /&gt;      _values = values;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)&lt;br /&gt;  {&lt;br /&gt;      return _include &amp;amp;&amp;amp; (_values.Contains(values[parameterName].ToString(), StringComparer.InvariantCultureIgnoreCase));&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The ValuesConstraint class is instantiated by passing in the list of values, and an an optional flag which indicates if the route parameter should be a match or not be a match for these values. It can be used in the following fashion:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;routes.MapRoute(string.Empty, &quot;{controller}/{id}&quot;,&lt;br /&gt;new { controller = &quot;Home&quot;, action = &quot;Index&quot;, id = UrlParameter.Optional },&lt;br /&gt;new&lt;br /&gt;{&lt;br /&gt;controller = &quot;Clubs|Members|Shops&quot;,&lt;br /&gt;id = new ValuesConstraint(false, &quot;ClubMembers&quot;, &quot;Photos&quot;, &quot;News&quot;, &quot;Deals&quot;, &quot;Staff&quot;, &quot;Wall&quot;, &quot;About&quot;, &quot;OpeningHours&quot;, &quot;Info&quot;, &quot;Friends&quot;)&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;While the above would work it doesn&#39;t actually solve the problem of maintainability, because we&#39;re still hard-codign a list of strings representing the action methods on our controllers. So, the final piece of the puzzle is to create a method that outputs a list of all the action methods on controllers of our choosing:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;private string[] GetActionNames(params Type[] controllers)&lt;br /&gt;{&lt;br /&gt;  var actionNames = new List&lt;string&gt;();&lt;br /&gt;  foreach(Type controllerType in controllers)&lt;br /&gt;  {&lt;br /&gt;MethodInfo[] methodInfos = controllerType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);&lt;br /&gt; foreach(var method in methodInfos)&lt;br /&gt;  actionNames.Add(method.Name);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  return actionNames.ToArray();&lt;br /&gt;}&lt;br /&gt;&lt;/string&gt;&lt;/pre&gt;&lt;br /&gt;And then we can use it like this:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;var controllerActions = GetActionNames(typeof(ClubsController), typeof(MembersController), typeof(ShopsController));&lt;br /&gt;routes.MapRoute(string.Empty, &quot;{controller}/{id}&quot;,&lt;br /&gt;new { controller = &quot;Home&quot;, action = &quot;Index&quot;, id = UrlParameter.Optional },&lt;br /&gt;new&lt;br /&gt;{&lt;br /&gt; controller = &quot;Clubs|Members|Shops&quot;,&lt;br /&gt; id = new ValuesConstraint(false, controllerActions)&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now our &quot;{controller}/{id}&quot; will only be matched by URLs where &quot;{controller}&quot; equals &quot;Clubs&quot;, &quot;Members&quot;, or &quot;Shops&quot; and &quot;{id}&quot; does &lt;i&gt;not&lt;/i&gt; equal any action method name on any of these controllers. Any URL that does not match this route will then default to our, uhm, default route. Ta-dah!</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/8734739809477534274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=8734739809477534274' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/8734739809477534274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/8734739809477534274'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2011/11/route-constraints-working-with.html' title='Route Constraints: Working with conflicting routes in MVC'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-1881832601139408549</id><published>2011-10-13T12:16:00.008+01:00</published><updated>2011-10-14T09:21:47.394+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DateTime"/><category scheme="http://www.blogger.com/atom/ns#" term="Testing"/><title type='text'>Using DomainTime Instead of DateTime</title><content type='html'>In a &lt;a href=&quot;http://www.babel-lutefisk.net/2011/10/working-with-dates.html&quot;&gt;previous post about favouring DateTime.UtcNow over DateTime.Now&lt;/a&gt; I mentioned that I don&#39;t use the DateTime struct directly in code to &lt;font style=&quot;font-style:italic;&quot;&gt;obtain&lt;/font&gt; the current date or time. Instead I use what I call DomainTime, a wrapper around the DateTime struct. It looks like this:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;   public static class DomainTime&lt;br /&gt;   {&lt;br /&gt;       internal static DateTime OverrideForTesting = DateTime.MinValue;&lt;br /&gt;&lt;br /&gt;       public static DateTime UtcNow { get { return OverrideForTesting == DateTime.MinValue ? DateTime.UtcNow : OverrideForTesting.ToUniversalTime(); } }&lt;br /&gt;&lt;br /&gt;       public static DateTime Now { get { return OverrideForTesting == DateTime.MinValue ? DateTime.Now : OverrideForTesting; } }&lt;br /&gt;&lt;br /&gt;       public static DateTime Today { get { return OverrideForTesting == DateTime.MinValue ? DateTime.Today : OverrideForTesting.Date; } }&lt;br /&gt;&lt;br /&gt;       public static DateTime MaxValue { get { return DateTime.MaxValue; } }&lt;br /&gt;&lt;br /&gt;       public static DateTime MinValue { get { return DateTime.MinValue; } }&lt;br /&gt;&lt;br /&gt;       internal static void Reset()&lt;br /&gt;       {&lt;br /&gt;           OverrideForTesting = DateTime.MinValue;&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The whole point of using this class is that it makes it easy to test other classes that have some kind of time dependency. To use a contrived example, imagine that you&#39;ve got a class which will only do its work if the time is between 1am and 2am. It makes the decision (should I work or should I not?) by checking DateTime.Now.&lt;br /&gt;&lt;br /&gt;How do you test this? You _could_ run your tests just before 1am, between 1am and 2am, and then again after 2am - but that&#39;s just stupid. You should be able to run your tests anywhere, any time, and as many times as you want.&lt;br /&gt;&lt;br /&gt;The solution, here, is to make the class depend on DomainTime.Now instead. By doing so, you can&lt;br /&gt;override the current time during testing by setting it with the OverrideForTesting property.&lt;br /&gt;&lt;br /&gt;Note that this property is an internal property. Expose it to your test assemblies by using the&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;[assembly: InternalsVisibleTo(&quot;Your.Test.Assembly&quot;)]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;directive in the AssemblyInfo class in the assembly where DomainTime resides.&lt;br /&gt;&lt;br /&gt;Now you can test to your heart&#39;s content. It&#39;s just a matter of setting the appropriate DateTime for each test.&lt;br /&gt;&lt;br /&gt;One final note: The DomainTime.Reset() method is there for your SetUp() or TearDown() methods so that you can avoid having the DateTime set by one test bleed over into another test.</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/1881832601139408549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=1881832601139408549' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/1881832601139408549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/1881832601139408549'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2011/10/using-domaintime-instead-of-datetime.html' title='Using DomainTime Instead of DateTime'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-3324262435536074634</id><published>2011-10-13T10:08:00.007+01:00</published><updated>2011-10-14T11:52:01.701+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC"/><title type='text'>Binding Views to Navigation Elements</title><content type='html'>Last night I did a bit of work on how I bind views to navigation items. I have tended to include information about &#39;active tabs&#39; as part of the view model (which fits well with the idea of having one model per view) - but I didn&#39;t like the hierarchy of view models that emerged from it.&lt;br /&gt;&lt;br /&gt;UPDATE: After a an anonymous comment on this post I have updated the implementation to use ViewData rather than TempData as the commenter rightly pointed out that, while the TempData implementation will work, TempData is for redirect.&lt;br /&gt;&lt;br /&gt;What I ended up doing was sticking a piece of data in the ViewData dictionary and pulling it out in the view to determine which tab should be rendered as &#39;active&#39;. I created some extension methods for ViewData to do this:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt; &lt;br /&gt;public static class ViewDataExtensions&lt;br /&gt;{&lt;br /&gt; public static void SetNavigation&lt;T&gt;(this ViewDataDictionary viewData, T navElement)&lt;br /&gt; {&lt;br /&gt;  var key = GetNavKey(navElement);&lt;br /&gt;  viewData.Add(key, navElement);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;public static T GetNavElement&lt;T&gt;(this ViewDataDictionary viewData)&lt;br /&gt; {&lt;br /&gt;  var key = GetNavKey(typeof(T));&lt;br /&gt;  T t;&lt;br /&gt;  try&lt;br /&gt;  {&lt;br /&gt;   t = (T)viewData[key];&lt;br /&gt;  }&lt;br /&gt;  catch&lt;br /&gt;  {&lt;br /&gt;   t = default(T);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  return t;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static string GetNavKey&lt;T&gt;(T navElement)&lt;br /&gt; {&lt;br /&gt;  return GetNavKey(navElement.GetType());&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static string GetNavKey(Type t)&lt;br /&gt; {&lt;br /&gt;  return &quot;sitenav:&quot; + t.Name;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/pre&gt;&lt;br /&gt;Then I created an action filter which I can stick on a controller and/or an action. Notice the AttributeUsage which specifies the allowable targets and that the attribute can be applied more than once (this could be important if you&#39;ve got more than one menu):&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method, AllowMultiple = true)]&lt;br /&gt;public class BindNavigation : ActionFilterAttribute &lt;br /&gt;{&lt;br /&gt; private readonly object _navElement;&lt;br /&gt;&lt;br /&gt; public BindNavigation(object navElement)&lt;br /&gt; {&lt;br /&gt;  _navElement = navElement;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public override void OnActionExecuting(ActionExecutingContext filterContext)&lt;br /&gt; {&lt;br /&gt;  filterContext.Controller.ViewData.SetNavigation(_navElement);&lt;br /&gt;  base.OnActionExecuting(filterContext);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I apply this to a controller like this:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;   &lt;br /&gt;[BindNavigation(MainNavigation.Members)]&lt;br /&gt;public class MembersController : FlyingFieldsBaseController&lt;br /&gt;{&lt;br /&gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And an action like this:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt; &lt;br /&gt;[BindNavigation(ProfileNavigation.Wall)]&lt;br /&gt;public ActionResult Index(string id)&lt;br /&gt;{&lt;br /&gt; var model = _getMemberProfileViewQuery.Invoke(Guid.Parse(id));&lt;br /&gt; return View(model);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As you can tell I am using enumerations for my different &quot;types&quot; of navigation (main header nav, left&lt;br /&gt;hand nav for profile pages, left hand nav for club management pages, etc). The thing is, though, you&lt;br /&gt;can use anything you like - because TempData stores things as objects (you&#39;ll notice that my TempData extension methods use generics so you get type safety as well). You could, for example, store an object that holds the state for several layers of navigation if that&#39;s what you need.&lt;br /&gt;&lt;br /&gt;In the views you just do this:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;@{&lt;br /&gt;var currentSection = ViewData.GetNavElement&lt;profilenavigation&gt;();&lt;br /&gt;}  &lt;br /&gt;&lt;/profilenavigation&gt;&lt;/pre&gt;&lt;br /&gt;and use &#39;currentSection&#39; however you please. I just use it to determine if I should set a CSS &quot;selected&quot; class on my navigation items.&lt;br /&gt;&lt;br /&gt;Thoughts are welcome!&lt;/li&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/3324262435536074634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=3324262435536074634' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/3324262435536074634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/3324262435536074634'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2011/10/binding-views-to-navigation-elements.html' title='Binding Views to Navigation Elements'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-3803394246658667170</id><published>2011-10-05T12:49:00.005+01:00</published><updated>2011-10-14T09:22:45.370+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DateTime"/><category scheme="http://www.blogger.com/atom/ns#" term="Time Zone"/><category scheme="http://www.blogger.com/atom/ns#" term="UTC"/><title type='text'>Working with dates</title><content type='html'>Lately I&#39;ve been doing a good amount of work on a website feature that requires the output of a relative date and time. For example, a entry written on a user&#39;s wall (the website has social aspects) may be annoted with &quot;written by John Smith about two hours ago.&quot; It is a relatively straight forward task to accomplish this - but I thought I&#39;d write a few words about some pitfalls you may come across.&lt;br /&gt;&lt;br /&gt;Even if you have only every written the most trivial of applications you are likely to have used the DateTime structure in .NET (if you&#39;ve written .NET apps, that is). And you&#39;re very likely to have used DateTime.Now; Let&#39;s take a closer look at the DateTime structure. According to &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.datetime.aspx&quot;&gt;Microsoft&#39;s documentation&lt;/a&gt; a DateTime &quot;Represents an instant in time, typically expressed as a date and time of day.&quot; And, DateTime.Now &quot;Gets a DateTime object that is set to the current date and time on this computer, expressed as the local time.&quot;&lt;br /&gt;&lt;br /&gt;Cool. DateTime.Now is really handy for getting a handle on the current time, and we&#39;ve all used it. But now I&#39;m going to tell you that you shouldn&#39;t.&lt;br /&gt;&lt;br /&gt;DateTime.Now returns a DateTime object that represents &quot;the current date and time on this computer, expressed as the local time.&quot; As convenient as this may be, it&#39;s a potential source of trouble. &quot;This computer&quot; is the computer where the code executes. It could be your desktop machine, a development server, a production server, or a mobile device. The time on that machine depends on where the machine is located (which timezone it is in) and whether or not the machine is affected by daylight savings. So why is this a problem?&lt;br /&gt;&lt;br /&gt;The problem is that if you cannot guarantee that all the machines in your infrastructure are all in the same timezone and are equally affected (or not affected) by daylight savings, using DateTime.Now in your code will potentially yield different timestamps on different machines even if the call to DateTime.Now was made at exactly the same time on the machines in question. 1pm in Oslo, Norway, on October 5th 2011 is not the same time as 1pm in London, UK, on the same date. &quot;But that&#39;s just silly&quot;, I hear you say. &quot;All our infrastructure is in the same data centre in one place.&quot; OK. Fine. That may very well be the case. But what about your users. Where are they? Are all of them in the same time zone as your servers? And is it likely that you&#39;ll never grow beyond having only local users and having only one data centre?&lt;br /&gt;&lt;br /&gt;Even if your answer to the above questions is &quot;we&#39;ll never scale beyond one data centre and all our users are in the same place and always will be&quot; I think you should keep reading. It might just make your life a little simpler down the road. Just in case.&lt;br /&gt;&lt;br /&gt;The problem with DateTime.Now is that it always represents the local time of the machine on which the code executes, and you don&#39;t really want to worry about where that machine is, because doing so makes life as a developer painful. What you want to do instead is use DateTime.UtcNow which returns an instance of DateTime representing the Coordinated Universal Time (UTC) of &lt;i&gt;now&lt;/i&gt;. UTC is the local time of the server &lt;i&gt;less&lt;/i&gt; any timezone differences and &lt;i&gt;less&lt;/i&gt; any daylight savings difference. If you only ever store and use UTC DateTimes then none of your DateTime comparisons will ever have to take into consideration any time differences caused by time zones or daylight savings. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The only thing you now have to worry about is the thing you &lt;i&gt;should&lt;/i&gt; worry about, which is displaying the correct date to your end users. You&#39;ll have to adjust for the timezone they&#39;re in because a date for an event at 12pm in London should be rendered as 1pm for a user in Oslo (they&#39;re always an hour ahead of London time).&lt;br /&gt;&lt;br /&gt;Regardless of whether you use UTC or not, you&#39;ll always have to consider time zones and daylight savings when rendering dates for a user. Using UTC, that&#39;s all you&#39;ll have to worry about. If you use DateTime.Now, however, you&#39;ll also have to ensure that you know what the time offset of that DateTime instance is if you&#39;re going to compare it to another date, or if you&#39;re going to render it to a user. Pain in the arse (PITA).&lt;br /&gt;&lt;br /&gt;I reckon that you should &lt;i&gt;always&lt;/i&gt; use UTC times in your applications regardless of what your user base might look like. It makes life simpler from the start, and if you ever need to support users across different timezones you&#39;ll be a step ahead.&lt;br /&gt;&lt;br /&gt;So, as a rule, this is what I do:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Always call DateTime.UtcNow and &lt;i&gt;never&lt;/i&gt; DateTime.Now. (In fact, I don&#39;t use DateTime... I use &lt;i&gt;DomainTime&lt;/i&gt; which is a wrapper I&#39;ve created around DateTime. I&#39;ll write more about that in a later post).&lt;/li&gt;&lt;li&gt;Always treat DateTime stored in a database as UTC. This means that when I read that DateTime out of the database I specify that it is a UTC DateTime using the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.datetime.specifykind.aspx&quot;&gt;DateTime.SpecifyKind()&lt;/a&gt; method. This is very important, because the machine will by default treat any DateTime as local time.&lt;br /&gt;&lt;br /&gt;Note that if you&#39;re using an ORM such as NHibernate you need to tell the ORM that the date should be treated as UTC. With FluentNHibernate this is really simple:&lt;br /&gt;&lt;br /&gt;  Map(x =&amp;gt; x.DateCreated).CustomType&lt;utcdatetimetype&gt;().Not.Nullable();&lt;br /&gt;&lt;/utcdatetimetype&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Lastly, before displaying the date to the user, I apply the time difference between UTC and the user&#39;s location. There are several ways of doing this. For example you can have your users tell you which time zone they&#39;re in and you can apply the offset. Or, if your users are web users you can use Javascript&#39;s Date.getTimezoneOffset() method and apply the difference (in minutes) to your UTC date. &lt;a href=&quot;http://stackoverflow.com/questions/1194933/javascripts-date-gettimezoneoffset&quot;&gt;Check out this StackOverflow question&lt;/a&gt; for some specific pitfalls of that particular method.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;utcdatetimetype&gt;&lt;br /&gt;I&#39;ll follow up on this post with another post or two about displaying relative times and &lt;a href=&quot;http://www.babel-lutefisk.net/2011/10/using-domaintime-instead-of-datetime.html&quot;&gt;how to use a DomainTime wrapper around your dates&lt;/a&gt;.&lt;br /&gt;&lt;/utcdatetimetype&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/3803394246658667170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=3803394246658667170' title='32 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/3803394246658667170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/3803394246658667170'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2011/10/working-with-dates.html' title='Working with dates'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>32</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-4026140929944295765</id><published>2011-09-20T00:20:00.008+01:00</published><updated>2011-09-20T01:29:44.198+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET MVC"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC"/><category scheme="http://www.blogger.com/atom/ns#" term="NHibernate"/><category scheme="http://www.blogger.com/atom/ns#" term="Session Management"/><category scheme="http://www.blogger.com/atom/ns#" term="Unit of Work"/><title type='text'>NHibernate session management and MVC</title><content type='html'>NHibernate session management is one of these things that occasionally catches me out. Usually once it&#39;s set up on a project I forget about it because it just works, but recently I came across a problem on a project which prompted me to write this post. There&#39;s a lot to say about NHibernate session management and this post is just a small contribution to the plethora of articles on the subject.&lt;br /&gt;&lt;br /&gt;What follows here is my implementation of session management in an MVC web application (it shouldn&#39;t matter what version of MVC you&#39;re on). What I&#39;ve set out to accomplish is this:&lt;br /&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Define a unit of work by using NHibernate&#39;s ICurrentSessionContext&lt;/li&gt;&lt;li&gt;Enforce the unit of work by applying transaction management across controller calls.&lt;/li&gt;&lt;li&gt;Ensure that a session and transaction is available across multiple&lt;i&gt; &lt;/i&gt;calls to &lt;i&gt;child actions.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Make the session available for injection via my container of choice, Windsor.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;In order to make any of this happen my application needs a session factory. I&#39;m not going to go into the details of how I construct my session factory as it isn&#39;t really relevant to this post - but suffice to say that the creation of the session factory is triggered by the Application_Start() method in Global.asax - and that I store the session factory as a static property on the HttpApplication. Actually, there is one&lt;i&gt; &lt;/i&gt;aspect of the session factory which &lt;i&gt;is&lt;/i&gt; relevant to this post - but I&#39;ll come back to that a little later.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;The Unit of Work&lt;/b&gt;&lt;/div&gt;&lt;div&gt;In web applications the obvious scope for a unit of work is a web request. Everything that happens, persistence-wise, between when a new request arrives and when the same request completes, can be treated as a unit of work. In other words, the changes to state in your application that takes place within a single web request should be atomic; the should either be persisted or rolled back at the end of the web request.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;With this in mind I&#39;ve set up the following methods on Global.asax:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;private void OnBeginRequest(object sender, EventArgs args)&lt;br /&gt;{&lt;br /&gt;  if(RequestMayRequirePersistence(sender as HttpApplication) &amp;amp;&amp;amp; Factory != null)&lt;br /&gt;  {&lt;br /&gt;      var session = Factory.OpenSession();&lt;br /&gt;      session.FlushMode = FlushMode.Auto;&lt;br /&gt;      ManagedWebSessionContext.Bind(HttpContext.Current, session);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private void OnEndRequest(object sender, EventArgs args)&lt;br /&gt;{&lt;br /&gt;  if (RequestMayRequirePersistence(sender as HttpApplication) &amp;amp;&amp;amp; Factory != null)&lt;br /&gt;  {&lt;br /&gt;      ManagedWebSessionContext.Unbind(HttpContext.Current, Factory);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Ignore the call to RequestMayRequirePersistence - this is just a helper method to check whether the request is for a resource that may require an NHibernate session, such as a controller.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When a request arrives, I call OpenSession() on the session factory to obtain a new session. Then I &lt;i&gt;bind&lt;/i&gt; this session to the current HttpContext by calling the Bind method on NHibernate&#39;s ManagedWebSessionContext.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Let&#39;s take a step back. Remember that I said that there&#39;s one aspect of the session factory set-up that&#39;s relevant? Well, we&#39;ve already come to it. In order for this solution to work we need to tell the session factory which type of session &lt;i&gt;context&lt;/i&gt; to use. A session context defines the &lt;i&gt;scope&lt;/i&gt; of given session instance. In other words, if a session instance belongs to a context then the NHibernate session factory will keep serving up that same instance whenever a call is made to OpenSession() within that context. We can tell NHibernate which session context to use when setting up the session factory. Using FluentNHibernate syntax you can set up NHibernate to use the ManagedWebSessionContext by adding this to your session factory fluent config:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;   .ExposeConfiguration(config =&amp;gt;&lt;br /&gt;    config.SetProperty(Environment.CurrentSessionContextClass,&lt;br /&gt;    typeof(ManagedWebSessionContext).AssemblyQualifiedName))&lt;br /&gt;&lt;/pre&gt;Now let&#39;s go back to handlers for BeginRequest and EndRequest. In addition to telling NHibernate which session context we want to use, we have to define when to bind and unbind the current session from that context. That&#39;s what the OnBeginRequest and OnEndRequest methods do; they define the actual scope of our NHibernate session, our unit of work.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You can read more about NHibernate session context &lt;a href=&quot;http://nhforge.org/wikis/reference2-0en/context-sessions.aspx&quot;&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Enforcing our Unit of Work&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Now we&#39;ve defined a unit of work for our application. However, this unit of work is no good to us yet because we still need to set up some controls around when transactions are created, committed, and rolled back. For my application I think the following rules make sense:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Begin a transaction when an action method starts executing&lt;/li&gt;&lt;li&gt;If an exception occurs during the execution of an action, roll back the transaction.&lt;/li&gt;&lt;li&gt;If an exception occurs during the rendering of a &lt;i&gt;view&lt;/i&gt;, roll back the transaction&lt;/li&gt;&lt;li&gt;If the execution of a controller and rendering of a view complete successfully, commit the transaction&lt;/li&gt;&lt;li&gt;Any calls to &lt;i&gt;child actions&lt;/i&gt; should &#39;enlist&#39; in the current transaction, and a child action should never roll back or commit a transaction.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;I have implemented these rules through an ActionFilterAttribute which I&#39;ve called, uhm, TransactionAttribute. It looks like this:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;public class TransactionAttribute : ActionFilterAttribute&lt;br /&gt;    {&lt;br /&gt;     //Create transaction&lt;br /&gt;     public override void OnActionExecuting(ActionExecutingContext filterContext)&lt;br /&gt;     {&lt;br /&gt;         var controller = filterContext.Controller as IPersistenceController;&lt;br /&gt;&lt;br /&gt;         if (controller != null &amp;amp;&amp;amp; !filterContext.IsChildAction)&lt;br /&gt;         {&lt;br /&gt;             controller.CurrentSession.BeginTransaction();&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     //rollback on exception&lt;br /&gt;     public override void OnActionExecuted(ActionExecutedContext filterContext)&lt;br /&gt;     {&lt;br /&gt;         var controller = filterContext.Controller as IPersistenceController;&lt;br /&gt;&lt;br /&gt;         if (controller != null &amp;amp;&amp;amp; !filterContext.IsChildAction)&lt;br /&gt;         {&lt;br /&gt;             ITransaction transaction = controller.CurrentSession.Transaction;&lt;br /&gt;             if (transaction.IsActive)&lt;br /&gt;             {&lt;br /&gt;                 if (filterContext.Exception != null)&lt;br /&gt;                 {&lt;br /&gt;                     transaction.Rollback();&lt;br /&gt;                 }&lt;br /&gt;             }&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     //commit transaction, or rollback on exception&lt;br /&gt;     public override void OnResultExecuted(ResultExecutedContext filterContext)&lt;br /&gt;     {&lt;br /&gt;         var controller = filterContext.Controller as IPersistenceController;&lt;br /&gt;         if (controller != null &amp;amp;&amp;amp; !filterContext.IsChildAction)&lt;br /&gt;         {&lt;br /&gt;             ITransaction transaction = controller.CurrentSession.Transaction;&lt;br /&gt;             base.OnResultExecuted(filterContext);&lt;br /&gt;             try&lt;br /&gt;             {&lt;br /&gt;                 if (transaction.IsActive)&lt;br /&gt;                 {&lt;br /&gt;                     if (filterContext.Exception != null)&lt;br /&gt;                         transaction.Rollback();&lt;br /&gt;                     else&lt;br /&gt;                         transaction.Commit();&lt;br /&gt;                 }&lt;br /&gt;             }&lt;br /&gt;             finally&lt;br /&gt;             {&lt;br /&gt;                 transaction.Dispose();&lt;br /&gt;             }&lt;br /&gt;         }&lt;br /&gt;         base.OnResultExecuted(filterContext);&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;There are really only two things worth noting here:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Controllers are cast to IPersistenceController. IPersistenceController defines a single property ISession CurrentSession {get;set;} which is used to obtain the current session.&lt;/li&gt;&lt;li&gt;I check the IsChildAction property of the ActionExecutingContext to make sure that child actions don&#39;t mess with the current transaction.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;You could argue that having every controller implement &lt;i&gt;IPersistenceController&lt;/i&gt; is a bad thing and that letting the controllers know about &lt;i&gt;ISession &lt;/i&gt;is even worse - and I&#39;d probably tend to agree with you. If you don&#39;t like this approach you can of course abstract the access to the current session away from the controller. I&#39;ve opted for this approach because of ease of implementation; Windsor - which I&#39;ll talk about in a minute - resolves all controllers for me, and therefore sets the ISession on the IPersistenceController.CurrentSession property automatically.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Making the Session Available to Windsor&lt;/b&gt;&lt;/div&gt;&lt;div&gt;The last piece of the puzzle is to make ISession available to Windsor so that it can be injected:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;   container.Register(Component.For&lt;ISession&gt;()&lt;br /&gt;              .UsingFactoryMethod(() =&amp;gt; MvcApplication.Factory.GetCurrentSession())&lt;br /&gt;              .LifeStyle.PerWebRequest);&lt;br /&gt;&lt;/pre&gt;Note the use of a factory method, and the call to MvcApplication.Factory.&lt;i&gt;GetCurrentSession()&lt;/i&gt;. When Windsor needs to resolve an instance of ISession it will call &lt;i&gt;GetCurrentSession()&lt;/i&gt; on the application&#39;s session factory. The &lt;i&gt;current session&lt;/i&gt; is governed by the &lt;i&gt;session context&lt;/i&gt; which we set up earlier. See? So Windsor will be handed the same instance of ISession every time it asks the factory for it during the course of a single web request.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The last thing to notice is the lifestyle that&#39;s chosen for the ISession instance: PerWebRequest. If you choose anything other than this lifestyle you&#39;ll run into trouble:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;If you set the lifestyle to Transient then Windsor will dispose of ISession if it disposes of any objects that have been injected with ISession&lt;/li&gt;&lt;li&gt;If you set the lifestyle to Singleton then Windsor will break the scope of the Unit of Work we&#39;ve so carefully set up and you&#39;ll end up with a single session for the lifetime of the application.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;Summary&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;In this post I&#39;ve shown one way of managing NHibernate sessions in the context of an ASP.NET MVC application. There are many ways of doing this, but this way seems to work well for me. Comments are welcome!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/4026140929944295765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=4026140929944295765' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/4026140929944295765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/4026140929944295765'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2011/09/nhibernate-session-management-and-mvc.html' title='NHibernate session management and MVC'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-8518145800574149105</id><published>2011-02-14T09:25:00.001+00:00</published><updated>2011-02-14T09:26:44.642+00:00</updated><title type='text'>Reflector is becoming a paid-for tool</title><content type='html'>Sadly, RedGate is &lt;a href=&quot;http://www.red-gate.com/products/dotnet-development/reflector/announcement&quot;&gt;breaking their promise&lt;/a&gt; (or, as they call it, &#39;intention&#39;) of keeping Reflector free of charge. So hurry, get your copy of Reflector now, before you have to pay for it.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/8518145800574149105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=8518145800574149105' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/8518145800574149105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/8518145800574149105'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2011/02/reflector-is-becoming-paid-for-tool.html' title='Reflector is becoming a paid-for tool'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-6315190992989019290</id><published>2011-02-07T09:41:00.003+00:00</published><updated>2011-02-07T09:57:56.256+00:00</updated><title type='text'>Hadlow: IDependencyResolver Is Broken</title><content type='html'>In my haste and determination to use MVC 3.0&#39;s dependency resolver in order to enable injection on attributes I took some suggestions from &lt;a href=&quot;http://www.cprieto.com/index.php/2010/07/30/windsor-service-locator-for-asp-net-mvc3-preview-1/&quot;&gt;Christian Prieto&#39;s&lt;/a&gt; blog post and implemented a Windsor-backed IDependencyResolver. It worked well and, despite the fact that I was effectively embracing an &lt;a href=&quot;http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx&quot;&gt;anti-pattern&lt;/a&gt; and using &lt;a href=&quot;http://underground.infovark.com/2010/06/18/the-service-locator-pattern-is-the-new-global-variable/&quot;&gt;a new global variable&lt;/a&gt;, I was pretty happy with the solution.&lt;br /&gt;&lt;br /&gt;I&#39;d overlooked something really fundamental, however. Mike Hadlow points this out in his &lt;a href=&quot;http://mikehadlow.blogspot.com/2011/02/mvc-30-idependencyresolver-interface-is.html&quot;&gt;recent post on Code Rant&lt;/a&gt;. The issue is simply this: IDependencyResolver doesn&#39;t support a mechanism for &lt;span style=&quot;font-style:italic;&quot;&gt;releasing&lt;/span&gt;&lt;span&gt; components, and this poses a problem when using a container such as Windsor as backing for the resolver. If you can&#39;t release components &lt;a href=&quot;http://kozmic.pl/2010/08/19/must-windsor-track-my-components/&quot;&gt;you&#39;ll eventually end up leaking memory&lt;/a&gt;.&lt;/span&gt;&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;In hindsight I should have stopped and listened more carefully to that gut feeling that told me I was doing something dirty when I embraced the service locator.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And for the first time I feel a bit let down by the MVC team; &lt;a href=&quot;http://bradwilson.typepad.com/blog/2010/07/service-location-pt1-introduction.html&quot;&gt;why did they ignore this&lt;/a&gt; (see the comments trail)? I have to agree with Hadlow on this: They shouldn&#39;t shout about the IDependencyResolver being container-agnostic when it blatantly isn&#39;t.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So this afternoon I&#39;ll be rolling my good old WindsorControllerFactory back into the solution.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/6315190992989019290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=6315190992989019290' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/6315190992989019290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/6315190992989019290'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2011/02/hadlow-idependencyresolver-is-broken.html' title='Hadlow: IDependencyResolver Is Broken'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-6202081623251178990</id><published>2011-01-18T10:06:00.002+00:00</published><updated>2011-01-18T10:15:49.783+00:00</updated><title type='text'>Annoying issue with the ASP.NET membership databases</title><content type='html'>In order to speed up making changes to my databases during development I&#39;ve set up a .cmd script that drops and recreates my project databases, and fills them with some seed data. This is pretty expedient, though in hindsight I think a solution using something like Visual Studio&#39;s database projects might be better. At any rate, I digress...&lt;br /&gt;&lt;br /&gt;Yesterday I ran into a problem with the ASP.NET membership database tables. I kept getting this error:&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style:italic;&quot;&gt;The &#39;System.Web.Security.SqlMembershipProvider&#39; requires a database schema compatible with schema version &#39;1&#39;.  However, the current database schema is not compatible with this version.  You may need to either install a compatible schema with aspnet_regsql.exe (available in the framework installation directory), or upgrade the provider to a newer version.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;My script uses the aspnet_regsql.exe tool to install the membership database - so this was very strange. The actual error stems from data missing in the aspnet_SchemaVersions table. Depending on what membership features you have installed you will have some of the following rows in this table:&lt;br /&gt;&lt;br /&gt;common 1 1&lt;br /&gt;health monitoring 1 1&lt;br /&gt;membership 1 1&lt;br /&gt;personalization 1 1&lt;br /&gt;profile 1 1&lt;br /&gt;role manager 1 1&lt;br /&gt;&lt;br /&gt;The weird thing for me, though, was that this data was present! So, what was going on?&lt;br /&gt;&lt;br /&gt;The error was only thrown by IIS, but not by the development web server in VS. Discovering this prompted me to restart IIS... and the problem went away.&lt;br /&gt;&lt;br /&gt;In my case I figured out that the problem was that my database script had deleted all the rows in the aspnet_SchemaVersions &lt;span style=&quot;font-style:italic;&quot;&gt;after&lt;/span&gt; the database had been created. This caused the error in the first place. When I updated the script, however, the error didn&#39;t go away (in IIS) and I can only guess that this must be because this data had been cached in the IIS worker process.</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/6202081623251178990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=6202081623251178990' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/6202081623251178990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/6202081623251178990'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2011/01/annoying-issue-with-aspnet-membership.html' title='Annoying issue with the ASP.NET membership databases'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-2790368409847545129</id><published>2010-12-02T13:42:00.010+00:00</published><updated>2010-12-08T23:31:39.287+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Testing"/><category scheme="http://www.blogger.com/atom/ns#" term="Windsor"/><title type='text'>Verifying that Windsor is configured correctly</title><content type='html'>Yesterday I experienced some very weird behaviour in an MVC app I am building - and it all came down to me being sloppy when configuring Windsor to resolve instances of HttpContextBase. In my haste I&#39;d left the lifestyle configuration as default, rendering the resolved HttpContextWrapper as a singleton. That&#39;s not particularly useful.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When this happened it occurred to me that it would be nice to be able to verify that you&#39;ve configured Windsor in the correct way and that you haven&#39;t inadvertently changed that configuration during development. So I knocked up a couple of extension methods on IWindsorContainer that can help. With these you can run tests such as:&lt;/div&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;_container.ShouldMap&amp;lt;IDisposable&amp;gt;().To&amp;lt;MyClass&amp;gt;();&lt;br /&gt;_container.ShouldMap&amp;lt;IDisposable&amp;gt;().To&amp;lt;MyClass&amp;gt;().WithLifeStyle(LifestyleType.PerWebRequest);&lt;br /&gt;_container.ShouldMap&amp;lt;HttpContextBase&amp;gt;().WithLifeStyle(LifestyleType.Singleton);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;All you need is an instance of IWindsorContainer and the extension methods below. Note, that if you&#39;re testing stuff that&#39;s environment dependent (i.e. resolving HttpContext which is dependent on the ASP.NET runtime) you&#39;ll have to set that up separately. Lastly, I&#39;ve built this against NUnit - but refactoring to other frameworks should be easy.&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;    public static class ContainerExtensions&lt;br /&gt;    {&lt;br /&gt;        public class ComponentWrapper&lt;br /&gt;        {&lt;br /&gt;            public IWindsorContainer Container { get; set; }&lt;br /&gt;            public ComponentModel Component { get; set; }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public static ComponentWrapper ShouldMap&amp;lt;T&amp;gt;(this IWindsorContainer container) where T : class&lt;br /&gt;        {&lt;br /&gt;            List&amp;lt;GraphNode&amp;gt; graphNodes = new List&amp;lt;GraphNode&amp;gt;(container.Kernel.GraphNodes);&lt;br /&gt;            List&amp;lt;ComponentModel&amp;gt; componentModels = new List&amp;lt;ComponentModel&amp;gt;(Convert(graphNodes));&lt;br /&gt;&lt;br /&gt;            ComponentModel componentModel = componentModels.Find(x =&amp;gt; x.Service == typeof(T));&lt;br /&gt;            if (componentModel == null)&lt;br /&gt;                throw new AssertionException(string.Format(&amp;quot;Service {0} has not been registered in the container&amp;quot;,&lt;br /&gt;                                                           typeof (T).FullName));&lt;br /&gt;&lt;br /&gt;            return new ComponentWrapper {Container = container, Component = componentModel};&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public static ComponentWrapper To&amp;lt;T&amp;gt;(this ComponentWrapper wrapper) where T : class&lt;br /&gt;        {&lt;br /&gt;            Type serviceType = wrapper.Component.Service;&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;                var instance = wrapper.Container.Resolve(serviceType);&lt;br /&gt;&lt;br /&gt;                if (instance.GetType() != typeof(T))&lt;br /&gt;                    throw new AssertionException(string.Format(&amp;quot;Expected implementation of {0} to be {1}, but was {2}&amp;quot;,&lt;br /&gt;                                                               serviceType,&lt;br /&gt;                                                               typeof(T).FullName, instance.GetType()));&lt;br /&gt;            }&lt;br /&gt;            catch(Exception exception)&lt;br /&gt;            {&lt;br /&gt;                throw new AssertionException(string.Format(&amp;quot;An exception was thrown when resolving {0}. The exception message is: {1}&amp;quot;,&lt;br /&gt;                                                               serviceType, exception.Message), exception);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return wrapper;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public static ComponentWrapper WithLifeStyle(this ComponentWrapper wrapper, LifestyleType expectedExpectedLifestyle)&lt;br /&gt;        {&lt;br /&gt;            VerifyLifestyle(wrapper.Component.LifestyleType, expectedExpectedLifestyle);&lt;br /&gt;            return wrapper;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private static void VerifyLifestyle(LifestyleType actualLifestyle, LifestyleType expectedLifestyle)&lt;br /&gt;        {&lt;br /&gt;            if (actualLifestyle == LifestyleType.Undefined &amp;amp;&amp;amp; expectedLifestyle == LifestyleType.Singleton)&lt;br /&gt;                return;&lt;br /&gt;&lt;br /&gt;            if(expectedLifestyle != actualLifestyle)&lt;br /&gt;                throw new AssertionException(string.Format(&amp;quot;Expected lifestyle {0} but was {1}&amp;quot;,&lt;br /&gt;                                                           expectedLifestyle, actualLifestyle));&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private static IEnumerable&amp;lt;ComponentModel&amp;gt; Convert(List&amp;lt;GraphNode&amp;gt; graphnodes)&lt;br /&gt;        {&lt;br /&gt;            foreach(GraphNode node in graphnodes)&lt;br /&gt;                yield return node as ComponentModel;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/2790368409847545129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=2790368409847545129' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/2790368409847545129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/2790368409847545129'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2010/12/verifying-that-windsor-is-configured.html' title='Verifying that Windsor is configured correctly'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-5645627773516560369</id><published>2010-11-30T08:47:00.004+00:00</published><updated>2010-11-30T09:10:39.891+00:00</updated><title type='text'>Encapsulating boolean return types.</title><content type='html'>.Net 4 introduced some changes to the way DataAnnotations ValidationAttributes work. Pre .NET 4 you would check the validity of a property on a class by attributing it with a ValidationAttribute (custom or otherwise) and then calling the IsValid():bool method. This is straight forward and logical. However; this approach leaves a bit to be desired. If IsValid() returns &lt;i&gt;false&lt;/i&gt;, what exactly is it that invalidates my property? It would be better if validation was approached differently, and this is what DataAnnotations in .NET 4 does.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In .NET 4 the use of IsValid():bool is discouraged. In fact, if you create a new custom validation attribute (extending ValidationAttribute) and &lt;i&gt;do not override IsValid()&lt;/i&gt; before you call it, it will throw a NotImplementedException with the message &quot;IsValid(object value) has not been implemented by this class.  The preferred entry point is GetValidationResult() and classes should override IsValid(object value, ValidationContext context).&quot;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As you can see, you&#39;re encouraged to override an overload of IsValid(). If you look closer you&#39;ll see that the overload does not return true/false, but instead returns a &lt;i&gt;ValidationResult &lt;/i&gt;which is a wee bit more informative. Also, the overload is &lt;i&gt;protected&lt;/i&gt; - so you can&#39;t call it externally. Instead you call the GetValidationResult() method to see what the result of validation is.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Why is this better than just returning true or false? It&#39;s because a ValidationResult carries information about &lt;i&gt;why&lt;/i&gt; validation failed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You might now think that this is a bit overkill for scenarios in which validation is successful. In this case, more often than not, all you care about is knowing that validation has passed and that you can carry on. The ValidationResult class facilitates this by applying the &lt;a href=&quot;http://en.wikipedia.org/wiki/Null_Object_pattern&quot;&gt;Null Object Pattern&lt;/a&gt; and encapsulating a static property called ValidationResult.Success against which you can compare the ValidationResult instance returned to you by GetValidationResult() (ValidationResult.Success always returns null, because a null validation result signifies successful validation).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This approach doesn&#39;t just apply to validation scenarios. Ayende Rahien talks about why and how he uses this approach &lt;a href=&quot;http://ayende.com/Blog/archive/2010/11/13/what-is-wrong-with-this-api-answer.aspx&quot;&gt;here&lt;/a&gt;. If you have a method that returns true/false and there is no more relevant information available, fine. However, if the&lt;i&gt; &lt;/i&gt;true/false answer masks other information then the approach of encapsulating the answer in a class is better.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/5645627773516560369/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=5645627773516560369' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/5645627773516560369'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/5645627773516560369'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2010/11/encapsulating-boolean-return-types.html' title='Encapsulating boolean return types.'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-2628293554728237314</id><published>2010-11-29T09:50:00.002+00:00</published><updated>2010-11-29T09:55:20.048+00:00</updated><title type='text'>Go on. Get NuGet.</title><content type='html'>I spent most of yesterday afternoon (Sunday!) messing about with FluentNHibernate, trying to compile the source to .NET4, NHibernate 3 Beta, and Castle Windsor 2.5.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What. A. Waste. Of. Time.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Sometimes I just don&#39;t think. Somebody out there would probably have done this already, right? The answer to that question is &lt;i&gt;yes&lt;/i&gt;. But it wasn&#39;t until I happened upon the &lt;i&gt;&lt;a href=&quot;http://code.google.com/p/hornget/&quot;&gt;hornget&lt;/a&gt;&lt;/i&gt;&lt;a href=&quot;http://code.google.com/p/hornget/&quot;&gt; project&lt;/a&gt; that bells started ringing: &quot;Hmmmm.... that&#39;s awfully similar to &lt;a href=&quot;http://nuget.codeplex.com/&quot;&gt;NuGet&lt;/a&gt;, isn&#39;t it?&quot; Yes, it is. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Suffice to say that 10 minutes after this realisation I had FluentNHibernate running in my solution, &lt;i&gt;with&lt;/i&gt; NHibernate 3 Beta &lt;i&gt;and&lt;/i&gt; Castle Windsor 2.5.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So if you haven&#39;t already, go on and get NuGet.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/2628293554728237314/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=2628293554728237314' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/2628293554728237314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/2628293554728237314'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2010/11/go-on-get-nuget.html' title='Go on. Get NuGet.'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-6041567620226293102</id><published>2010-11-25T09:01:00.009+00:00</published><updated>2011-07-12T15:52:15.426+01:00</updated><title type='text'>Testing routes with MVC3 RC1 and .NET 4</title><content type='html'>&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial, sans-serif; font-size: 13px; &quot;&gt;Yesterday I found myself needing to test some MVC routes. I wanted to avoid setting up all the mocking infrastructure needed to do so, and decided to use the &lt;a href=&quot;http://mvccontrib.codeplex.com/&quot;&gt;MVCContrib project&lt;/a&gt; to ease the work. However, I am building an MVC 3 RC1 app on .NET 4 - and MVCContrib targets .NET 3.5 and MVC 2, so I quickly ran into trouble.&lt;br /&gt;&lt;br /&gt;I tried converting the solution to .NET 4.0 - but it was too time consuming to do so. Instead I ripped out the pieces I needed, i.e. the route testing extension methods, and built a new assembly targeting the right versions of the framework. And I replaced RhinoMocks with Moq.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial, sans-serif; font-size: 13px; &quot;&gt;Using the Mvc.TestHelper assembly you can easily test routes with syntax like this:&lt;/span&gt;&lt;/div&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&quot;~/&quot;.ShouldMapTo&amp;lt;HomeController&amp;gt;(x =&amp;gt; x.Index());&lt;br /&gt;&quot;~/Account/&quot;.ShouldMapTo&amp;lt;AccountController&amp;gt;(x =&amp;gt; x.Register(null));&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;br /&gt;&lt;b style=&quot;font-family: arial, sans-serif; font-size: 13px; &quot;&gt;&lt;i&gt;Note: I take zero credit for this work. All the source code is taken directly from the MVCContrib project.&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 13px; &quot;&gt;I have made the &lt;a href=&quot;https://bitbucket.org/peppershrimp/mvc.testhelper&quot;&gt;source available on BitBucket&lt;/a&gt; so that you can test your MVC 3 routes. The project uses NUnit and Moq for testing.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/6041567620226293102/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=6041567620226293102' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/6041567620226293102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/6041567620226293102'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2010/11/testing-routes-with-mvc3-rc1-and-net-4.html' title='Testing routes with MVC3 RC1 and .NET 4'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-8701846061351352114</id><published>2010-01-21T13:57:00.002+00:00</published><updated>2010-01-21T14:01:09.854+00:00</updated><title type='text'>The LIBUSWKAIQ anti-pattern</title><content type='html'>&lt;p&gt;Design patterns have been all the rage for quite some time now, and with them have come an increased awareness of patterns that pretend to be design patterns but really are anti-patterns; a pattern that appears obvious but really is far from optimal in practice (read: stupid).&lt;/p&gt;&lt;p&gt;A relatively recent (and greenfield) implementation where I work is built around such an anti-pattern. We&#39;ve named this lovely piece of instant legacy the LIBUSWKAIQ anti-pattern. It&#39;s pronounced &quot;Libbus-wah-cake&quot; and stands for &quot;Let It Blow Up So We Know About It Quickly.&quot;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;This pattern gives you free license to forget about exception handling and encourages applications to fall over and die if any exceptional circumstances arise.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;This pattern encourages you to throw exceptions with the explicit purpose of killing your app.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;This pattern hates error handling.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;This pattern creates needy applications that require immediate attention.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;This pattern encourages 3am support calls. This pattern wants your support developers to always be deprived of sleep. This patterns wants you to spend your ENTIRE support budget.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;This pattern appeals to lazy people.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Don&#39;t do this! Handle your errors. Keep your apps running. Put errors to the side and let humans deal with it as soon as it is conveniently possible. Don&#39;t stop your entire business process running just because it experienced a minor &#39;blip.&#39;&lt;/p&gt;&lt;p&gt;You&#39;re smarter than this. Don&#39;t get sucked into becoming a Libbus-wah-caker. &lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/8701846061351352114/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=8701846061351352114' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/8701846061351352114'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/8701846061351352114'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2010/01/libuswkaiq-anti-pattern.html' title='The LIBUSWKAIQ anti-pattern'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-1527660273534997975</id><published>2009-09-28T18:26:00.002+01:00</published><updated>2009-09-28T18:36:10.171+01:00</updated><title type='text'>Literate Programming</title><content type='html'>A while back I wrote &lt;a href=&quot;http://www.babel-lutefisk.net/2009/03/names-and-importance-of-semantics.html&quot;&gt;a rather lengthy entry about the significance of strong and clear naming conventions&lt;/a&gt;, and I spent some time explaining how well-defined, unambiguously named methods with to-the-point parameter names end up reading like sentences out of a book.&lt;br /&gt;&lt;br /&gt;Today &lt;a href=&quot;http://eugoogoolizer.blogspot.com/&quot;&gt;a friend&lt;/a&gt; pointed me to the &lt;a href=&quot;http://www.literateprogramming.com/index.html&quot;&gt;Literate Programming website&lt;/a&gt;, where the following snippet can be found:&lt;br /&gt;&lt;br /&gt;&quot;I believe that the time is ripe for significantly better documentation of programs, and that we can best achieve this by considering programs to be works of literature. Hence, my title: &#39;Literate Programming.&#39;&lt;br /&gt;&lt;br /&gt;Let us change our traditional attitude to the construction of programs: Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do.&lt;br /&gt;&lt;br /&gt;The practitioner of literate programming can be regarded as an essayist, whose main concern is with exposition and excellence of style. Such an author, with thesaurus in hand, chooses the names of variables carefully and explains what each variable means. He or she strives for a program that is comprehensible because its concepts have been introduced in an order that is best for human understanding, using a mixture of formal and informal methods that reinforce each other.&quot;&lt;br /&gt;&lt;br /&gt;When I read this I immediately thought: YES! This is exactly what I&#39;ve been trying to say. Code should not be a language for a select &#39;elite&#39; that prides itself on obscurity. It should be something that can be read with ease and even by someone with very little technical understanding. I dare say that if you achieve that, you&#39;ve achieved maintainable code.</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/1527660273534997975/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=1527660273534997975' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/1527660273534997975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/1527660273534997975'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2009/09/literate-programming.html' title='Literate Programming'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-6980128326618987584</id><published>2009-09-23T12:29:00.001+01:00</published><updated>2009-09-23T12:31:06.776+01:00</updated><title type='text'>Boolean Polymorphism</title><content type='html'>I think &lt;a href=&quot;http://eugoogoolizer.blogspot.com/2009/09/boolean-polymorphism.html&quot;&gt;this is a rather good article&lt;/a&gt; about the pitfalls of large parameter lists and code maintainability.</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/6980128326618987584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=6980128326618987584' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/6980128326618987584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/6980128326618987584'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2009/09/boolean-polymorphism.html' title='Boolean Polymorphism'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-3136633895546715579</id><published>2009-07-22T08:39:00.001+01:00</published><updated>2009-07-22T10:23:45.905+01:00</updated><title type='text'>Factory Assembly Lines, Red Cars, and TDD</title><content type='html'>For the last five weeks I have been supporting developers on a project that makes full use of automated unit and integration tests, including the use of a mocking framework. The frameworks of choice are NUnit and Moq, which is fairly standard stuff. What makes our little project special, though, is that the developers were all (bar one) completely new to the concepts of unit testing and mocking! This has made for some interesting challenges. All the developers are highly capable and intelligent people, so they&#39;ve adopted the new principles with amazing speed. But as anyone who&#39;s transitioned to TDD will know, the mindset required is very different from that of &#39;traditional&#39; development. As such, I&#39;ve had to do a lot of mentoring during the last month or so.&lt;br /&gt;&lt;br /&gt;There&#39;s nothing quite like having a good example to go by when you&#39;re trying to learn something new. That&#39;s the case with TDD as well. I also think that in order to learn TDD and the test-first discipline you need something more. What&#39;s needed is a school of thought. Perhaps even a dogma. I think that this is far more important than specific examples of how to do specific things, because with the correct line of thinking you&#39;ll arrive at good solutions to any of your testing problems. It was with this in mind that I wrote what follows; a rather absurd testing scenario involving a factory assembly line and lots of red cars.&lt;br /&gt;&lt;br /&gt;What I want to address now is the creation of tests, and the scope of this discussion includes what a test should test (the scope of the test, if you like), where boundaries should be drawn, and how such decisions should influence your design while you’re coding. For now, imagine that you are responsible for the production line of cars, and that you want to be able to test that a car is painted in the colour that you have specified.&lt;br /&gt;&lt;br /&gt;How would you go about testing such a thing? The first thing that springs to mind is perhaps to instruct your assembly line (people and machines) to build you a red car, and then go have a look at the car when it’s built to see if it is, in fact, red. Such an approach would certainly work, but it would be a hell of an expensive test! What if the car came out the wrong colour? Or a different shade of red than you expected? You’d have to keep cranking out cars while making adjustments until you get the colour right, and that’s just not a sensible approach. &lt;br /&gt;&lt;br /&gt;Of course, this example is absurd because you would never do that if you owned a car factory – but I’ve chosen this example exactly for that reason; you’re clearly doing too much work just to check that the car turns out with the right colour. Too much work. That’s a key thing to remember.&lt;br /&gt;&lt;br /&gt;How could you improve on the process? Well, you might start by skipping the entire “build-me-a-car” bit and focus on the paint job itself. A car is painted by a big robot with lots of paint guns, and this whole mess takes place at the end when the car has been assembled and all non-metallic surfaces have been carefully masked etc. Since this is where paint is applied we can narrow our testing to this machine. We can put a piece of paper in front of the paint gun and ask it to colour the paper red. If things turn out unexpectedly, we can easily repeat the test. Paper is cheap, and even paint is much cheaper than a car. Not only that, but repeating the test is much faster also. This test is therefore infinitely better than the first test. We’re doing much less work, it’s costing less, and we’ve focused right down on the thing that makes a car red (or any other colour). Focus. That’s another key thing to remember.&lt;br /&gt;&lt;br /&gt;Let’s stop and think about focus for a moment. In the first test, if a car turned out burgundy rather than the sports-car red you’d imagined, where would you make your adjustments before testing again? Sure, you may know that it’s the big ol’ paint robot at the end of the line that does the work, but how do you get your instructions to it? Is there a human involved? At what stage of the car assembly do you have to ‘input’ the colour? Right at the start? Does anything happen to your colour instruction while the car is being built? Does one human tell another, or is it written down on paper and later typed into a computer? It should be fairly easy to see that a test with such wide focus (or no focus at all) is prone to all kinds of environmental noise that can affect the output and thus make accurate testing difficult. So focus is important.&lt;br /&gt;&lt;br /&gt;Now, we’ve narrowed our focus to the robot that paints the car, and we’ve devised a test that involves the robot spraying paint onto a sheet of paper. This is, in the scheme of things, probably a decent test. But we can do better. Does the paint gun produce the colour? No it doesn’t. The purpose of the paint gun is to deliver paint at the correct pressure and velocity, and to ensure that the nozzle produces a mist of paint with exactly the right droplet size etc. We can certainly  use the paint gun to test colour, but since it’s got nothing to do with producing the colour of paint, we should see if we can create a better test. We should narrow our focus again.&lt;br /&gt;&lt;br /&gt;If you keep repeating the process of narrowing your focus you’ll eventually end up at the part of the machine that mixes paint to create specific colours. Now the focus seems to be about right (you can probably narrow things down even further, though). The part of the machine that mixes the paint is what’s responsible for the colour that eventually ends up on the car. Arguably, you can take the whole paint element out of it because your paint is likely to be generic and colourless – so you can just focus on the mixing of pigments. But I don’t want to be too pedantic, either.&lt;br /&gt;&lt;br /&gt;Now that we’ve got the focus right, we’ve got to get our test right. We’re trying to verify that when we ask for red, red is what we get. But if you think about it, red isn’t very specific either. Is it blood red? Burgundy? Maroon? A bit more on the pink side of the spectrum? To try and test for red isn’t specific enough. And here’s another thing to be mindful of. Be specific. Don’t test for red, but instead test for a specific shade of red. And so your test will start to change shape as well. Rather than testing for a colour you’ll find that you’ll be testing that the paint mixer dispenses the correct amounts of red, green, and blue (the basic components of the RGB colour system) in order to produce a specific shade of a specific colour. Now you’ve got a good test. A valuable test. A test you can write home about.&lt;br /&gt;&lt;br /&gt;Such a test can be carried out without much work, it’s focused (it involves only part of a sub-system), and it’s very specific (it tests conditions for very specific input). All these things are good. In the context of the car factory you’ve now got a fast, cheap, repeatable, and accurate test that’ll verify that your factory is capable of cranking out cars in every colour of the spectrum.&lt;br /&gt;&lt;br /&gt;Well, that’s actually a half truth. Or less than a half truth. You’ve only created a test for mixing pigments. You’ve not tested that the right amount of mixed pigment is added to the correct volume of paint. Nor have you tested that the paint gun actually works like it should and that the paint-robot moves like it should. And there isn’t a single test, yet, for any other aspect of the car assembly line. All this is beyond the scope of this discussion, but suffice to say that if you are a car producer hell-bent on making big bucks you’d apply the same principles as above to creating tests for every single aspect of your production line.&lt;br /&gt;&lt;br /&gt;Now let’s try and relate this example back to software. The car assembly line would likely be implemented as a number of applications and/or services that each carry out specific tasks (basic assembly, welding, engine installation etc). The paint-robot might be one such application. The robot’s paint gun would be represented by a class, as would the pigment mixer. And the actual mixing of pigments would probably be represented as a single method on the pigment mixer class. That’s the unit you’d be testing. You wouldn’t write a test that invokes all those applications because it would require too much work and be too difficult, and it would result in an inherently inaccurate test.&lt;br /&gt;&lt;br /&gt;So, when you’re writing tests and designing your code you should always make sure that what you’re working on lends itself to testing (it doesn’t require a lot of work), it is focused, and very specific. If what you are testing is part of something much, much larger then ensure that your unit is isolated. You do this by using mock objects for its dependencies. If you can’t use mock objects for whatever reason you should stop and think about why that is and see if you can change your design. Maybe you don’t have to. Maybe you can run your test in a slightly wider context without doing too much work or becoming too unfocused or non-specific. If you can, fine. If you can’t – change your design.&lt;br /&gt;&lt;br /&gt;Careful thinking about how you’d test the code you are going to write will help you write better systems. As with anything, it requires practice and experience (and you’ll never stop learning) and it’s possible to go terribly wrong – but if every decision you make is the result of careful, informed consideration the likelihood of failure is minimal. Good tests are tests that are focused on one system, and specifically a single function of that one system – and that do very little work in order to test that function. Make the creation of such tests your goal, and you’ll quickly learn how to write clean, robust, and testable code.</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/3136633895546715579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=3136633895546715579' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/3136633895546715579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/3136633895546715579'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2009/07/factory-assembly-lines-red-cars-and-tdd.html' title='Factory Assembly Lines, Red Cars, and TDD'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-7409740332116860753</id><published>2009-06-22T11:25:00.002+01:00</published><updated>2009-06-22T11:30:34.220+01:00</updated><title type='text'>PartCover - an alternative to NCover?</title><content type='html'>I&#39;ve been looking for a cheap or free tool for measuring NUnit test coverage and just stumbled upon &lt;a href=&quot;http://sourceforge.net/projects/partcover/&quot;&gt;PartCover&lt;/a&gt;. I&#39;ve installed it and fiddled with it and it seems to be an OK tool. It&#39;s Open Source, too - which I think is great.&lt;br /&gt;&lt;br /&gt;I have to say, though, that the documentation is poor and the application itself is buggy (I experienced a critical exception when trying to save a coverage report to file). Despite this, I&#39;ll take a buggy PartCover over NCover which would set me back $650 for a license! &lt;br /&gt;&lt;br /&gt;Might write more about this later. Check it out!</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/7409740332116860753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=7409740332116860753' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/7409740332116860753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/7409740332116860753'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2009/06/partcover-alternative-to-ncover.html' title='PartCover - an alternative to NCover?'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-3868202232761648336</id><published>2009-03-13T11:12:00.002+00:00</published><updated>2009-03-13T11:29:05.089+00:00</updated><title type='text'>Names and the Importance of Semantics</title><content type='html'>I&#39;ve taken the below &#39;post&#39; from some documentation I&#39;ve recently written for the developers where I&#39;m currently working. It appears to me that, in general, developers (and, indeed, architects) spend far too little time thinking about names and naming conventions. Personally I spend &lt;span style=&quot;font-style:italic;&quot;&gt;hours&lt;/span&gt; thinking about names. Good names are an &lt;span style=&quot;font-style:italic;&quot;&gt;incredibly&lt;/span&gt; important aspect of good software design. Anyway - if you care to read on, this is what I&#39;ve said on the subject so far:&lt;br /&gt;&lt;br /&gt;Aside from writing code that is correct, efficient, and actually works, the most important aspect of software development is, arguably, naming. Choosing good names for namespaces, classes, methods, and properties (even member variables, local variables and parameters) is incrediby important (and therefore also difficult) because the semantics they convey. A name must be unambiguous and clearly convey the purpose and function of the named component when viewed in isolation, as well as when it is viewed in the context of its root namespace, immediate namespace, class, and so on.&lt;br /&gt;&lt;br /&gt;Good type and namespace names leave little room for misunderstandings and mistakes because of ambiguity. Namespaces and types defined in the .NET Framework are very clearly named throughout and the semantics of each name are typically very clear. A good example of this is the &lt;code&gt;System.IO&lt;/code&gt; namespace.&lt;br /&gt;&lt;br /&gt;The &lt;code&gt;System.IO&lt;/code&gt; namespace name is unambiguous because it is short, because the relationship between the components of the namespace (&quot;System&quot; and &quot;IO&quot;) is clear, and because each component of the namespace is named well semantically:&lt;br /&gt;&lt;br /&gt;&quot;System&quot; implies a logical grouping of functionality that is &#39;close to the machine&#39; or &#39;close to the framework&#39;. The &quot;System&quot; namespace, by virtue of its name, is very clearly not a task or application specific namespace. &lt;br /&gt;&lt;br /&gt;While it may be argued that the word &quot;System&quot; is ambigous because it can encapsulate so much functionality (and varied functionality at that), when seen in its context (it is the main root namespace of the entire framework) the name is still very clear.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&quot;IO&quot; is a very old and commonly used abbreviation (&quot;InputOutput&quot;) in computer science and is always associated with data transfer between devices (both internal and peripheral). The immediate association of &quot;IO&quot; is that of file read/write operations, and this is exactly the kind of functionality that the classes in this namespace provides.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;System.IO&lt;/code&gt; is therefore a really good namespace because the semantics of the first component&#39;s name lends meaning to the other. &quot;System&quot; tells the developer that we&#39;re dealing with general, non application-specific functionality, and &quot;IO&quot; implies that the functionality is file-operation specific.&lt;br /&gt;&lt;br /&gt;The &lt;code&gt;File&lt;/code&gt; class within the &lt;code&gt;System.IO&lt;/code&gt; namespace is another good example of good naming. Its fully qualified name, &lt;code&gt;System.IO.File&lt;/code&gt;, makes it absolutely clear what the class is and what it does - it&#39;s very clearly a representation of a file on a file system and provides file operations to the caller.&lt;br /&gt;&lt;br /&gt;The methods on the &lt;code&gt;File&lt;/code&gt; class are also very well named. A couple of examples illustrate how clear, short names can convey a lot of information when viewed in their proper context:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;public static System.IO.FileStream Open(string path, System.IO.FileMode mode)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The method name &lt;code&gt;File.Open&lt;/code&gt; is in itself very clear; it is obvious that the &lt;code&gt;Open()&lt;/code&gt; method will open a file on a disk. There is sometimes a tendency to be too specific when naming methods - the above method might for example be called &lt;code&gt;OpenFile()&lt;/code&gt;. Viewed entirely in isolation, the second method name, &lt;code&gt;OpenFile()&lt;/code&gt;, is clearer than &lt;code&gt;Open()&lt;/code&gt; - but when viewed in the context of its class, &lt;code&gt;OpenFile()&lt;/code&gt; is obviously a poorer name than &lt;code&gt;Open()&lt;/code&gt; because the context (the &lt;code&gt;File&lt;/code&gt; class) already makes it obvious that we are in fact dealing with files!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;public static bool Exists(string path)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This method name is clear because it can be phrased as a question with a simple yes/no (or true/false) answer: &quot;Does this file exist?&quot; &lt;br /&gt;&lt;br /&gt;&lt;code&gt;public static void Move(string sourceFileName, string destFileName)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This method name is unambiguous (clearly &lt;code&gt;File.Move()&lt;/code&gt; is a method that moves a file on a file system), but pay particular attention to the parameter names; &lt;code&gt;sourceFileName&lt;/code&gt; and &lt;code&gt;destFileName&lt;/code&gt; leave no doubt about what you are dealing with. If this method&#39;s signature is paraphrased into a sentence it would read something like &quot;move this source file to this destination.&quot;&lt;br /&gt;&lt;br /&gt;The above examples above illustrate the importance of context when constructing names in software. A named element must make sense in isolation, but it is also very  important that it makes sense contextually. Methods must be named so that the name itself carries the correct semantics, but the method&#39;s parameters (and return type) should be named in a manner so as to add further semantic value to the method&#39;s signature.</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/3868202232761648336/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=3868202232761648336' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/3868202232761648336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/3868202232761648336'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2009/03/names-and-importance-of-semantics.html' title='Names and the Importance of Semantics'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-6567263821881354852</id><published>2009-03-10T22:23:00.003+00:00</published><updated>2009-03-10T22:25:14.902+00:00</updated><title type='text'>Orange Mocha Frappucino</title><content type='html'>This is just a quick note to those of you that I know read this blog - because I know you know Steve. He&#39;s started blogging over on &lt;a href=&quot;http://eugoogoolizer.blogspot.com/&quot;&gt;Orange Mocha Frappucino&lt;/a&gt;. First post is about handling web.config in unit tests. Good one, Steve!</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/6567263821881354852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=6567263821881354852' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/6567263821881354852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/6567263821881354852'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2009/03/orange-mocha-frappucino.html' title='Orange Mocha Frappucino'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-289256828328827961</id><published>2009-02-24T12:44:00.002+00:00</published><updated>2009-02-24T12:56:18.546+00:00</updated><title type='text'>James Joyce .NET</title><content type='html'>Last week, after doing a code review, I coined the term &quot;James Joyce .NET&quot;. Though the James Joyce factor isn&#39;t particularly .NET specific (I&#39;m sure there are Ruby, C++, Java, and most certainly C developers out there who do things in similarly cryptic manners), I think the term has a nice ring to it. And in fairness to Joyce, I think the code I reviewed was far less readable than Ulysses.&lt;br /&gt;&lt;br /&gt;Aside from software that works and &quot;does its thing&quot; in a reliable manner, clients care a lot about code that&#39;s maintainable. The client may not &lt;span style=&quot;font-style:italic;&quot;&gt;know&lt;/span&gt; that they care about this, at least not at first - but once you tell them that a change is going to take three weeks to complete &quot;because of this, that, and the other&quot; (because the code you&#39;ve written isn&#39;t maintainable) you bet your sweet ass they start caring. They care not because of the state of your code; they care because of the cost. And rightly so.&lt;br /&gt;&lt;br /&gt;There are many key things to consider when writing maintainable code but the subject of my current rant will be &lt;span style=&quot;font-style:italic;&quot;&gt;readability&lt;/span&gt;. Does your code read like a book? Probably not (hey, it&#39;s &lt;span style=&quot;font-style:italic;&quot;&gt;not&lt;/span&gt; fiction) - and that&#39;s OK. But do your method names and signatures read like sentences? Could you translate the body of your methods into short little textual paragraphs that clearly illustrate what they do? If you answered &quot;no&quot; to both of these questions it&#39;s probably time to stop and think a little.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style:italic;&quot;&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Disclaimer:&lt;/span&gt; I&#39;m renowned for harping on about ideals and I&#39;ve been caught out many a time falling short of my own mark. That said, I stick to my ideals because without them we&#39;ve got nowhere to go.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To start with, code must be legible. That means you have to choose names (for your classes, methods, parameters, variables) that clearly indicate purpose. Favour readability over brevity when creating names. Second, your names must make semantic sense. A class-method name combination should be completely unambiguous, easy to read, and clearly convey &quot;what you get&quot;. Classes and methods should do what it says on the tin. Don&#39;t be obscure, don&#39;t be ambiguous.&lt;br /&gt;&lt;br /&gt;Third: Use the appropriate constructs for the job. Don&#39;t embed an algorithm in a property. Don&#39;t use private properties. Properties are there to &lt;span style=&quot;font-style:italic;&quot;&gt;expose&lt;/span&gt; aspects of a class, so if you&#39;re not going to expose it, use a private member variable instead. Don&#39;t use indexers for anything but accessing collection data. Don&#39;t use generics unless you &lt;span style=&quot;font-style:italic;&quot;&gt;need&lt;/span&gt; generic code, and then only if generics give you something that a typed parameter list doesn&#39;t (using interface/abstract classes instead of concrete types).&lt;br /&gt;&lt;br /&gt;Seriously, think long and hard about &lt;span style=&quot;font-style:italic;&quot;&gt;any&lt;/span&gt; code you write. Just because something works doesn&#39;t make it good. And give some thought to those people that come after you. Will they be able to understand what you&#39;ve done? You might very well be a genius and the best thing since sliced bread but really, what good is that if nobody understands what you&#39;ve done? Don&#39;t obfuscate your code by being lazy, too clever, or by using constructs in a way that they were not intended.&lt;br /&gt;&lt;br /&gt;&amp;lt;/ rant&amp;gt;</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/289256828328827961/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=289256828328827961' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/289256828328827961'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/289256828328827961'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2009/02/james-joyce.html' title='James Joyce .NET'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-5943086310072484216</id><published>2009-02-18T13:28:00.000+00:00</published><updated>2009-02-18T13:29:17.175+00:00</updated><title type='text'>What not to do 5 minutes before a meeting...</title><content type='html'>I typically don&#39;t read the &lt;a href=&quot;http://www.metro.co.uk/&quot;&gt;Metro&lt;/a&gt; magazine on my way to work, but today I did. And there was a little snippet in there about a YouTube video that was supposed to be very funny. This tickled my curiousity, so when I found myself with a couple of minutes to spare before a meeting this morning, I went to YouTube to watch the clip about &lt;a href=&quot;http://www.youtube.com/watch?v=txqiwrbYGrs&quot;&gt;David After Dentist&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Bad decision. It took me a good 10 minutes to stop grinning and get my sudden bursts of laughter under control. Not good when someone&#39;s called a meeting with you to give you an update on serious matters.&lt;br /&gt;&lt;br /&gt;Funny as hell though :-)</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/5943086310072484216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=5943086310072484216' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/5943086310072484216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/5943086310072484216'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2009/02/what-not-to-do-5-minutes-before-meeting.html' title='What not to do 5 minutes before a meeting...'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-652174954000901332.post-1772397627166916151</id><published>2008-11-13T21:32:00.004+00:00</published><updated>2008-11-13T21:44:30.210+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="MVC"/><category scheme="http://www.blogger.com/atom/ns#" term="Quality"/><category scheme="http://www.blogger.com/atom/ns#" term="Testing"/><title type='text'>Brittleware</title><content type='html'>This is really just an observation, and a highly subjective one at that. To any die-hard ASP.NET traditionalist out there: This isn&#39;t meant as an attack, so don&#39;t take it as one.&lt;br /&gt;&lt;br /&gt;I&#39;ve been working on the ASP.NET MVC framework together with my buddy Steve for a while now and we&#39;ve been trying out a lot of different things while getting to grips with this new (and much better) way of doing things. We&#39;ve been trying to establish our own patterns for developing MVC applications, and while doing so we have experimented and written a lot of code, and very few tests.&lt;br /&gt;&lt;br /&gt;During this phase of experimentation I truly came to love the MVC framework for its flexibility and elegance, but for some reason I had this nagging feeling that all was not well. It was a familiar feeling, too, and one that I associate specifically with web development. But I couldn&#39;t put my finger on it.&lt;br /&gt;&lt;br /&gt;Then just a couple of days ago I realised what it was. We&#39;d decided to start building in earnest, and using the MVC framework in anger. Nothing would be written unless it was tested. And after a couple of hours of intense controller-testing I suddenly realised that the uneasy feeling was gone, and in its place was a feeling of security and contentment.&lt;br /&gt;&lt;br /&gt;What I&#39;d felt before was the same feeling I always had when writing ASP.NET applications. Things just felt &lt;span style=&quot;font-style:italic;&quot;&gt;brittle&lt;/span&gt; and ready to break. I could go to any length in order to ensure that the application did what it should, worked like intended, and would fail gracefully - but somehow that feeling of brittleness never went away completely. I didn&#39;t have any tests, no way of verifying that I was still on the right path, the straight and narrow. And writing MVC applications without tests gave me that same feeling because really, I was no better off.&lt;br /&gt;&lt;br /&gt;With the introduction of tests that feeling of brittleness disappeared and instead the application felt robust. Solid. Stable. Reliable. Add any number of synonyms. If you believe in TDD you know what I&#39;m talking about.&lt;br /&gt;&lt;br /&gt;I don&#39;t know if there&#39;s a moral to this story, but the realisation I had has confirmed to me yet again how &lt;span style=&quot;font-style:italic;&quot;&gt;correct&lt;/span&gt; it is to develop everything with tests first. There simply isn&#39;t another way.</content><link rel='replies' type='application/atom+xml' href='http://www.babel-lutefisk.net/feeds/1772397627166916151/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=652174954000901332&amp;postID=1772397627166916151' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/1772397627166916151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/652174954000901332/posts/default/1772397627166916151'/><link rel='alternate' type='text/html' href='http://www.babel-lutefisk.net/2008/11/brittleware.html' title='Brittleware'/><author><name>Øyvind Valland</name><uri>http://www.blogger.com/profile/17595718624373482981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_uJz81f9t7xk/SfDLYNHy4qI/AAAAAAAAADc/DowkLpwcutw/S220/oyvind_avatar_89x89.JPG'/></author><thr:total>0</thr:total></entry></feed>