tag:blogger.com,1999:blog-35504293486096097792024-03-13T05:39:11.685-07:00Coding for a LivingThis code was written by a toolRichard Naglehttp://www.blogger.com/profile/01948075949080934517noreply@blogger.comBlogger16125tag:blogger.com,1999:blog-3550429348609609779.post-32656888209538155522009-10-08T00:00:00.000-07:002009-10-08T07:12:18.776-07:00On Duct Tape ProgrammersTo: <a href="http://www.joelonsoftware.com/items/2009/09/23.html">Duct tape programmers</a><br /><br />Enjoy, your skin-of-your teeth deliveries, your fingers-crossed deployments, your days lost fire fighting the same issues over and over again. Have fun, wading through incomprehensible spaghetti code, and cut 'n' pasting your "one off" solutions all the shop. Smile sweetly as you work late into the night figuring out the latest screw up.<br /><br />By all means, cling onto you outdated methods like its still 1988. But please, allow me to work the way I want to work. And, do me a favour, stay outta my codebase.Richard Naglehttp://www.blogger.com/profile/01948075949080934517noreply@blogger.com0tag:blogger.com,1999:blog-3550429348609609779.post-45021083630276527432009-10-07T00:00:00.000-07:002009-10-07T06:01:04.115-07:00Mind The GapAgile, in whatever form, has a set of core practices - iterative development, unit testing, continuous integration, etc. You can, by all means, choose not to include one or more of these core practices; but you better make damn sure you fill the gap with something else or you're headed for big trouble.<br /><br />For instance, one core practice is the creation of acceptance tests for each story (use case) at the same time, or before, the story is being worked on. These acceptance tests are often created by test professionals who form part of the team. If you don't do this but instead see testing as seperate to development, then you need to do something to plug the knowledge gap. The testers are not going to know what to test. How can they? They're not involved in planning or daily stand ups. The usual response then is that "Agile doesn't work for testing because it is document-lite." Wrong, agile is document-lite because everyone is involved in the development process. Take that away and you have a gap. A gap you must fill. In this case by writing up your stories in detail for the testers to test against.<br /><br />You see, the agile core practices work together, so that the whole is greater than the sum of the parts. Take one of the parts away and you may very well find the whole is broken. At this point you may decide agile doesn't work. Not true, you broke it!Richard Naglehttp://www.blogger.com/profile/01948075949080934517noreply@blogger.com0tag:blogger.com,1999:blog-3550429348609609779.post-91989947550007742792009-09-17T00:00:00.000-07:002009-09-17T04:07:06.672-07:00Waiting for Visual Studio<p>I find this funny and ironic......</p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_m9dgrIyvvp4/SrIX-RdEQCI/AAAAAAAAAB0/rbVqhCf-DII/s1600-h/VisualStudioIsBusy.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 152px;" src="http://2.bp.blogspot.com/_m9dgrIyvvp4/SrIX-RdEQCI/AAAAAAAAAB0/rbVqhCf-DII/s400/VisualStudioIsBusy.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5382390863265808418" /></a>Richard Naglehttp://www.blogger.com/profile/01948075949080934517noreply@blogger.com0tag:blogger.com,1999:blog-3550429348609609779.post-17027795041840700832009-07-14T04:36:00.000-07:002009-07-14T05:15:51.380-07:00Collapsing foreach Loops using LINQMuch of the business logic we have traditionally written has been buried in a heap of nested foreach loops and if statements. All this additional cermoney obfiscates the meaning of the code making finding what a method does more difficult.<br /><br />One the key strength of LINQ, as I see it, is in its ability to put your application's business logic center stage. By seperating your query from your command within each method, the clarity of those methods is greatly increased.<br /><br />Time for a example I think. Take the following example of traditional business logic:<br /><pre><br />public void FulfillOrders()<br />{<br />foreach(Customer customers in Customers)<br />{<br /> if(customer.CanPlaceOrders())<br /> {<br /> foreach(Order order in customer.Orders)<br /> {<br /> if(!order.IsShipped()<br /> {<br /> foreach(OrderLine line in order.Lines)<br /> {<br /> if(line.IsInStock())<br /> {<br /> customer.Ship(order, line);<br /> }<br /> else<br /> {<br /> customer.BackOrder(order, line);<br /> }<br /> }<br /> }<br /> } <br /> }<br />}<br />}<br /></pre><br />OK, I admit, not a great bit of DDD - but I'll live with that; its not the point of this blog. However this code, is fairly difficult to read and its going to quickly become unmaintainable as more business logic is heaped upon it. LINQ allows us to collapse down those foreach loops and if statements into a query thereby achieving command query seperation within the method.<br /><pre><br />public void FulfillOrders()<br />{<br />var allOrders = from customer in Customers<br /> from order in cutomer.Orders<br /> from line in order.Lines<br /> where customer.CanPlaceOrders()<br /> && !order.IsShipped<br /> select new {Customer = customer,<br /> Order = order,<br /> Line = line};<br /> <br />var shippable = from item in allOrders<br /> where item.IsInStock()<br /> select item;<br /> <br />var outOfStock = from item in allOrders<br /> where !item.IsInStock()<br /> select item;<br /> <br />foreach(var item in shippable)<br />{<br /> item.Customer.Ship(item.Order, item.Line);<br />}<br /> <br />foreach(var item in outOfStock)<br />{<br /> item.Customer.BackOrder(item.Order, item.Line);<br />}<br />}<br /></pre><br />Note, how in the allOrders query I am stacking up the "from" statements with no joins. This tells LINQ to do a cross join. But wouldn't this mean that every customer is joined to every order and every order line regardless of whether the customer owned the orders. Well, no; in the object model the Orders belong to the Customer and the OrderLines belong to the Orders. In this situation LINQ is smart enough to figure out which constraints should apply.<br /><br />In this new "LINQed-up" version we have clearly defined the queries (at the top) from the commands (at the bottom). This leads to clarity in code readability which in-turn leads to an increase in maintainability. Getting to grips with the syntax of LINQ can take some time, but the increase in code maintainability is well worth the effort.Richard Naglehttp://www.blogger.com/profile/01948075949080934517noreply@blogger.com0tag:blogger.com,1999:blog-3550429348609609779.post-21533243988627447462009-05-14T00:00:00.000-07:002009-05-14T13:35:55.261-07:00Redundant LayersThere been an interesting difference of opinion on the blogs of <a href="http://ayende.com/Blog/archive/2009/04/18/the-dal-should-go-all-the-way-to-ui.aspx">Ayende</a> and <a href="http://codebetter.com/blogs/gregyoung/archive/2009/04/23/repository-is-dead-long-live-repository.aspx">Greg Young</a> regarding the usage of the Repository pattern. Whilst some great points were made on both sides, I tend to agree with Ayende's view that advances in tooling can render patterns, that we have become accustomed to using, redundant. In this case he argues that NHibernate has left little reason to implement Repository any more.<br /><br />We segregate our applications into separate layers to help us manage the complexity of differing concerns. But we should accept that as new layers are added to an application, overall complexity of that application increases. If I was able to succinctly express my entire application in a single text file, without recourse to layers, I would. That is not (yet) possible so I use a layered approach.<br /><br />As advances are made in tooling we need to constantly re-evaluate our use of layers and patterns to see it they have been superseded by technological advances. Take MVC as an example; had I been a Smalltalk programmer fifteen years ago I would have needed to create a controller for every widget. As tooling has advanced this has become unnecessary and we now have a different kind of MVC.<br /><br />All too often I see applications where the architecture has been treated like a check list of layers. DTOs - check, domain - check, web services - check, repository - check; you get the idea. For me there has to be a very good reason for creating a new layer in my application. Do I really need that abstraction? If not, I don't feel compelled to include it. 90% of the applications I work with use a domain model. But that doesn't mean I always include that layer. A simple CRUD application with a few validation rules probably only requires a DAL and few DTOs and a presentation layer, for example.<br /><br />We need to constantly question ourselves and the decisions we make about architecture, and should only implement layers where we feel there is a need; not because that's the way we've always done so.Richard Naglehttp://www.blogger.com/profile/01948075949080934517noreply@blogger.com0tag:blogger.com,1999:blog-3550429348609609779.post-88706624681480676952009-04-22T00:00:00.000-07:002009-04-22T07:07:19.816-07:00Unity: Accessing the Creating ContainerHere's something I learned today about Microsoft's Unity.<br /><br />Often when an object is created through a container, you want to be able to access that container so that you can perform further resolutions. In the past my solution to this was to create a static class that held onto a single global instance of the container, essentially a Service Locator. The Service Locator could then be used by any class to access the same container.<br /><br />I have never been 100% happy with this because, as we all know, static global data is a *bad* thing which introduces dependencies which are hard to test. Today I discovered that when a container resolves a class which has a parameter of type IUnityContainer, the container will pass itself to that parameter. This means that the container can be passed down the chain of constructors without resorting to any global static nonsense.<br /><br />Here is my test:<br /><br /><pre><br />[Test]<br />public void ContainerPassesItselfToObjectsItCreates()<br />{<br /> var container = new UnityContainer();<br /> container.RegisterType<ClassCreatedByIoC>();<br /><br /> var objectCreatedByIoC = <br /> container.Resolve<ClassCreatedByIoC>();<br /> Assert.That(objectCreatedByIoC.Container, <br /> Is.SameAs(container));<br />}<br /><br />public class ClassCreatedByIoC<br />{<br /> public ClassCreatedByIoC(IUnityContainer container)<br /> {<br /> Container = container; <br /> }<br /><br /> public IUnityContainer Container { get; private set; }<br />}<br /></pre><br /><br /><br />I assume this works with injection methods and properties as well, but I haven't tested it.Richard Naglehttp://www.blogger.com/profile/01948075949080934517noreply@blogger.com0tag:blogger.com,1999:blog-3550429348609609779.post-90016269342900849062009-02-19T05:27:00.001-08:002009-02-19T05:30:07.925-08:00Edward WoodwardYesterday, I create a class called <a href="http://en.wikipedia.org/wiki/The_Equalizer">TheEqualizer</a>. This has made me way more happy than should be the case.<br /><br />Now I am worried that I more of geek than I thought I was.Richard Naglehttp://www.blogger.com/profile/01948075949080934517noreply@blogger.com0tag:blogger.com,1999:blog-3550429348609609779.post-42075733486401862592009-02-15T00:00:00.000-08:002009-02-15T00:27:40.578-08:00Scrum is Only a RecipeI like Scrum. It offers a great template for getting started with agile project management. But the important word in the previous sentence is <span style="font-weight: bold;">template</span>. I see too many teams worrying if they are doing scrum properly. That's not the point, doing Scrum properly is not the point. The point is trying to make a process that suits your current situation that is as agile as possible. Scrum is just a useful first stepping stone in getting there.<br /><br />The first time you cooked a recipe from a cookery book, you would follow it blindly. What else could you do? When you eat the food it may be too bland, so you next time you cook it you add a little salt; or it may be dry, so you adjust the cooking time. You use your previous experience to improve the outcome.<br /><br />Agile is like that: execute, reflect, improve, repeat. Sprint planning not working for you? Find another way to do it. Users cannot go three weeks without changing the scope? Shorten the iteration length. Don't feel constrained by the scrum process, remember it's only a template, change the bits that aren't working for you.<br /><br />Don't put up with crap food, improve your recipe.Richard Naglehttp://www.blogger.com/profile/01948075949080934517noreply@blogger.com0tag:blogger.com,1999:blog-3550429348609609779.post-88598792835867135962009-01-29T01:00:00.000-08:002009-01-29T05:35:22.528-08:00The x => FactorI may be swimming against the tide here, but I don't understand why it has become an idiom of C# to use <span style="font-style: italic;">x</span> as the parameter name in lambda expressions, as in:<br /><pre>var matching = list.ForEach(x => x.Version > 1)</pre>You wouldn't expect to see<br /><pre>foreach(var x in list)<br />{<br /> if(x.Version > 1)<br /> {<br /> yield return x;<br /> }<br />}</pre>I suspect it has a lot to with <span style="font-style: italic;">conciseness</span>. Whilst I highly value conciseness, <span style="font-style: italic;">I value readability over conciseness</span>.Richard Naglehttp://www.blogger.com/profile/01948075949080934517noreply@blogger.com0tag:blogger.com,1999:blog-3550429348609609779.post-6027857707159534752009-01-25T11:37:00.000-08:002009-01-25T11:39:06.283-08:00News Feeds Changed to FeedburnerI have changed the news feeds for this blog to use FeedBurner. You may want to update your links.Richard Naglehttp://www.blogger.com/profile/01948075949080934517noreply@blogger.com0tag:blogger.com,1999:blog-3550429348609609779.post-370272652526469432009-01-22T13:13:00.000-08:002009-01-23T06:40:39.305-08:00Explicit Exception Messages<span style="font-weight: bold;">What Happened</span><br /><br />I was adding code, deep in the bowels of the data <span class="blsp-spelling-corrected" id="SPELLING_ERROR_0">persistence</span> layer, to update auditing flags when entities where saved. The code <span class="blsp-spelling-corrected" id="SPELLING_ERROR_1">received</span> the <span class="blsp-spelling-error" id="SPELLING_ERROR_2">UserName</span> of the logged in user, looked it up in the User table, and placed the <span class="blsp-spelling-error" id="SPELLING_ERROR_3">UserId</span> in the <span class="blsp-spelling-error" id="SPELLING_ERROR_4">CreatedBy</span> or <span class="blsp-spelling-error" id="SPELLING_ERROR_5">ModifiedBy</span> field as appropriate. If the user could not be found a <span class="blsp-spelling-error" id="SPELLING_ERROR_6">SecurityException</span> was raised containing the message<br /><blockquote><span style="font-style: italic;">User with a <span class="blsp-spelling-error" id="SPELLING_ERROR_7">login</span> of [user name] cannot be found in the User table</span></blockquote>I tested it, everything worked fine, so I committed my changes and moved onto the next task; which was some changes to the Log-In page. Several hours, later I was ready to test my changes to the Log-In page. Whenever I hit the [OK] button, I got a <span class="blsp-spelling-error" id="SPELLING_ERROR_8">SecurityException</span> with the message<br /><blockquote><span style="font-style: italic;">User with a <span class="blsp-spelling-error" id="SPELLING_ERROR_9">login</span> of [user name] cannot be found in the User table</span></blockquote>Having already forgotten my earlier changes in the persistence layer, I took the message at face value and assumed I had messed up with my changes to the log in page. I then wasted a couple of hours undoing and redoing my work, but to no avail, the exception <span class="blsp-spelling-corrected" id="SPELLING_ERROR_10">stubbornly</span> remained.<br /><br />Eventually I was "smart" enough to follow the exception's stack trace which led me to the code I had changed earlier in data persistence layer. It turned out the membership provider was trying to update the <span class="blsp-spelling-error" id="SPELLING_ERROR_11">LastLoggedIn</span> date on the user, when my code tried to apply the <span class="blsp-spelling-error" id="SPELLING_ERROR_12">ModifiedBy</span> flag it couldn't get the logged in user because the log in process wasn't complete yet.<br /><br /><span style="font-weight: bold;">Lessons Learnt</span><br /><br /><ul><li>When you get an exception don't just look at the message, use the stack trace (duh?)<br /><br /></li><li>Make sure you throw appropriate exception types. The fact that I was getting a<span class="blsp-spelling-error" id="SPELLING_ERROR_13"> SecurityException</span> made me think this was a security issue, when in fact it was a data persistence issue. Something like <span class="blsp-spelling-error" id="SPELLING_ERROR_14">DatabaseRecordNotFoundException</span> would have been better.<br /><br /></li><li>Write exception messages that provide as much contextual information as possible. When writing the message don't assume that the message will be read in the same context as it is thrown. What do I mean by this? The error message I wrote made perfect sense in the context in which I was working, the data persistence layer. But once it escaped the DP layer, and bubbled up to the presentation it made much less sense and sent me off in the wrong direction, wasting time. Imagine how much worse this would be if it occurred some months later in production, and the error message arrived via the help desk with no stack trace.<br /></li></ul><br />The error message I finally decided upon read<br /><blockquote><span style="font-style: italic;">During a data persistence operation for [entity name] an attempt was made to update the auditing field [<span class="blsp-spelling-error" id="SPELLING_ERROR_15">CreatedBy</span>/<span class="blsp-spelling-error" id="SPELLING_ERROR_16">ModifiedBy</span>]. This failed because a user with a <span class="blsp-spelling-error" id="SPELLING_ERROR_17">login</span> of [user name] cannot be found in the User table</span></blockquote>Richard Naglehttp://www.blogger.com/profile/01948075949080934517noreply@blogger.com1tag:blogger.com,1999:blog-3550429348609609779.post-48690092268351291522009-01-22T01:00:00.000-08:002009-01-22T06:28:46.860-08:00A Pattern for Fluent SyntaxI've always been interested in making code as readable as possible and recently have become increasingly interested in fluent APIs. I have noticed that most of my fluent work has followed a similar pattern. I present this pattern here in the hope it helps others deliver their own fluent interfaces.<br /><br /><span style="font-weight: bold;font-size:130%;" >Fluent Interface</span><br /><br /><span style="font-style: italic;">Typically APIs provide methods with multiple parameters, many of which are not required for most uses. To overcome this, many programming languages have features such as method overloading or optional parameters. Whilst in many cases this helps API usage, it can result in bloated and hard-to-use APIs.<br /><br />Fluent APIs take a different approach, breaking down the API into its consituent parts and guiding the programmer through its usage. Fluent API takes advantage of the features of modern development environments, particularly "code-complete", to help provide this guidance. The aim for a fluent API is that it should be easy to write and easy to read.</span><br /><br /><span style="font-weight: bold;">How it Works</span><br /><br />The fluent syntax of your API will be provided by the public methods of a class; this class is named the <span style="font-style: italic;">Lexicon</span>. The key to the pattern, is that each method called should build up some state in the Lexicon and then return a reference back to a lexicon so that another method can be used from a Lexicon, and so on, to build up a meaningful statement.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_m9dgrIyvvp4/SXOVodpNLjI/AAAAAAAAABE/Zn9E3SKYgP8/s1600-h/fluent-class.gif"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 125px; height: 78px;" src="http://4.bp.blogspot.com/_m9dgrIyvvp4/SXOVodpNLjI/AAAAAAAAABE/Zn9E3SKYgP8/s400/fluent-class.gif" alt="" id="BLOGGER_PHOTO_ID_5292738509475229234" border="0" /></a><br />Consider the following fluent syntax for counting files in a folder:<br /><br /><pre><span style="font-size:85%;">int files = FileSystem.GetDrive("C:")<br /> .OpenFolder("Program File")<br /> .GetFileCount();</span></pre>FileSystem.GetDrive is the <span style="font-style: italic;">entry-point</span> into this fluent API. The entry-point will often be a constructor or static creation method. In all cases it will return a reference to a lexicon instance.<br /><br />OpenFolder is a <span style="font-style: italic;">continuation</span>. Continuations are methods that will set some state within the lexicon and then return an instance to the lexicon.<br /><br />GetFileCount is an <span style="font-style: italic;">end-point</span> for this API. An end-point is a method that takes some action based on the state of the lexicon. It will return some value that is the result of the fluent API call, or void, but will not return an instance of a lexicon.<br /><br />A lexicon can have multiple entry-point, continuations, and end-points. Where the fluent API is large, it is common to break the API into more than one lexicon. Control is passed from one lexicon to another by a continuation which returns an instance of a different lexicon type. The new lexicon will probably need to know the context of the original lexicon; this is normally done by passing the original lexicon to the new lexicon in its constructor.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_m9dgrIyvvp4/SXObv3LhPrI/AAAAAAAAABM/8yGrYhhpoks/s1600-h/fluent-class2.gif"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 394px; height: 78px;" src="http://2.bp.blogspot.com/_m9dgrIyvvp4/SXObv3LhPrI/AAAAAAAAABM/8yGrYhhpoks/s400/fluent-class2.gif" alt="" id="BLOGGER_PHOTO_ID_5292745233658887858" border="0" /></a><br /><span style="font-weight: bold;">When to use it</span><br /><br />Paradoxically, whilst a fluent API makes the reading and writing of that API easier, often the code making up that API is complicated by the addition of the fluent syntax. Consequently, Fluent Interface, should only be used in areas where the effort of extending the syntax is rewarded by frequent reuse. Typically, this applies to areas of cross-cutting concern such as configuration, logging or auditing.<br /><br />It is worth considering the complexity of the API before implementing it as fluent. For a simple interface with only a handful of methods it is probably not worth the effort.<br /><br /><br /><span style="font-weight: bold;">Example (C#)</span><br /><br />For this example we are going to consider a fluent syntax for obtaining information about the file system. I have split the API into multiple lexicons. This would possibly be considered overkill in the real-world but have done so here to make the example more complete.<br /><br />Firstly lets look at the FileSystem lexicon which provides fluent syntax for dealing with drives on your system:<br /><pre><span style="font-size:85%;"><br />public class FileSystem<br />{<br /> internal string DriveSpec { get; private set; }<br /><br /> private FileSystem(string driveSpec)<br /> {<br /> DriveSpec = driveSpec;<br /> }<br /><br /> // 1st entry point<br /> public static FileSystem GetDrive(string driveSpec)<br /> {<br /> if(!IsValidDrive(driveSpec))<br /> {<br /> throw new ArgumentException("Not a valid drive");<br /> } <br /> return new FileSystem(driveSpec);<br /> }<br /><br /> // 2nd entry point<br /> public static FileSystem MapDrive(string location, char assignedLetter)<br /> {<br /> string driveSpec = assignedLetter.ToString();<br /><br /> if(IsValidDrive(driveSpec))<br /> {<br /> throw new ArgumentException("Drive is already assigned");<br /> }<br /><br /> NetworkUtilities.MapDrive(location, assignedLetter);<br /><br /> return GetDrive(driveSpec);<br /> }<br /><br /> // continuation transfering control to another lexicon<br /> public FolderLexicon RootDirectory()<br /> {<br /> return new FolderLexicon(this,"\\");<br /> }<br /><br /> // 1st end point<br /> public long AvailableBytes<br /> {<br /> get<br /> {<br /> DriveInfo info = new DriveInfo(DriveSpec);<br /> return info.AvailableFreeSpace;<br /> }<br /> }<br /><br /> // 2nd end point<br /> public string Name<br /> {<br /> get<br /> {<br /> DriveInfo info = new DriveInfo(DriveSpec);<br /> return info.VolumeLabel; <br /> }<br /> } <br />}<br /></span></pre><br />And now the FolderLexicon used to hold the syntax for accessing information about file system folders<br /><pre><span style="font-size:85%;"><br /> public class FolderLexicon<br /> {<br /> // holds a reference to FileSystem<br /> // so the entire context can be discovered<br /> private readonly FileSystem drive;<br /><br /> private readonly StringBuilder path = new StringBuilder();<br /><br /> // entry point - note that this lexicon can<br /> // only be entered through a FileSystem<br /> internal FolderLexicon(FileSystem drive)<br /> {<br /> this.drive = drive;<br /> path.Append(drive.driveSpec);<br /> path.Append("\\");<br /> }<br /><br /> //continuation<br /> public FolderLexicon OpenFolder(string dirSpec)<br /> {<br /> path.Append("\\");<br /> path.Append(dirSpec);<br /> <br /> if(!Directory.Exists(path.ToString()))<br /> {<br /> throw new ArgumentException("Folder does not exist");<br /> }<br /><br /> return this;<br /> }<br /><br /> //end point<br /> public int GetFileCount()<br /> {<br /> DirectoryInfo dInfo = new DirectoryInfo(path.ToString());<br /> return dInfo.GetFiles().Length;<br /> }<br /> }<br /></span></pre>Richard Naglehttp://www.blogger.com/profile/01948075949080934517noreply@blogger.com3tag:blogger.com,1999:blog-3550429348609609779.post-48933503523700147232008-12-31T09:47:00.000-08:002008-12-31T09:51:34.491-08:00Agile ParentingCan agile be applied to parenting? I think so. Earlier today, my seven-year old daughter told me she found doing joined-up writing hard. My answer? <span style="font-style: italic;">If something is hard, do it more often.</span><br /><br />I think I may need a holiday, oh, I am on holiday.<br /><br />Happy new year.Richard Naglehttp://www.blogger.com/profile/01948075949080934517noreply@blogger.com0tag:blogger.com,1999:blog-3550429348609609779.post-19149544435330112632008-12-22T09:00:00.000-08:002008-12-22T09:17:23.739-08:00Assert YourselfWith my current role involving a long train journey, I have taken the <span class="blsp-spelling-corrected" id="SPELLING_ERROR_0">opportunity</span> to re-read Kent Beck's <a href="http://www.amazon.co.uk/Test-Driven-Development-Addison-Wesley-signature/dp/0321146530">Test-Driven Development, By Example</a>. Its one of my favourite technical books, and manages to provide a lot of useful information in quite a small tome. Although the examples are in Java and Python (both of which I have no experience of) I have no problem following them at all. I highly recommend it to anyone who is learning or using TDD.<br /><br />The book contains many ideas on how to implement and apply TDD, some of which I had forgotten. One such forgotten idea is <span style="font-style: italic;">Assert First</span>. The idea is that when you are writing a test method, the first thing you should write is the Assert statement. You can then work backwards from here to act and then arrange your test. It has a beautiful <span class="blsp-spelling-corrected" id="SPELLING_ERROR_1">symmetry</span> with the test first philosophy.<br /><br />I've been using Assert First quite a lot recently and have found it a very useful addition to my toolbox. It is particularly useful when you are writing the first test of a fixture and are unsure of how to proceed. Many times, in this situation, you know what the results should be but don't know how to get there. Assert first allows you to express your results and then rapidly work towards the solution with confidence.Richard Naglehttp://www.blogger.com/profile/01948075949080934517noreply@blogger.com0tag:blogger.com,1999:blog-3550429348609609779.post-62399694405032730902008-12-15T00:23:00.000-08:002008-12-15T05:52:58.352-08:00NUnit Tip: Rerun Tests After Each BuildThis may be one of those tips where everyone else is like, "Duh? You didn't know that?". But its a great tip, so (at the risk of ridicule) I'll present it anyway.<br /><br />You can set up the <span class="blsp-spelling-error" id="SPELLING_ERROR_0">NUnit</span> GUI application so that it re-runs the last test run after each build. If, like me, you have a dual screen setup, then you can do a build in Visual Studio on one screen and immediately see the test results in <span class="blsp-spelling-error" id="SPELLING_ERROR_1">NUnit</span> GUI on the other screen without having to do any task switching. I'm finding this a great time saver.<br /><br />To set this up:<ol><li>Launch the <span class="blsp-spelling-error" id="SPELLING_ERROR_2">NUnit</span> GUI</li><li>From the main menu select Tools | Options</li><li>Select "Assembly Reload" from the left hand side</li><li>Check the "Reload when test assembly changes" <span class="blsp-spelling-error" id="SPELLING_ERROR_3">checkbox</span></li><li>Check the "Re-run last tests run" <span class="blsp-spelling-error" id="SPELLING_ERROR_4">checkbox</span></li></ol><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_m9dgrIyvvp4/SUZfkhqj7FI/AAAAAAAAAAU/4XvH7UJGfJc/s1600-h/nunit-gui.gif"><img style="cursor: pointer; width: 400px; height: 252px;" src="http://2.bp.blogspot.com/_m9dgrIyvvp4/SUZfkhqj7FI/AAAAAAAAAAU/4XvH7UJGfJc/s400/nunit-gui.gif" alt="" id="BLOGGER_PHOTO_ID_5280012694255299666" border="0" /></a>Richard Naglehttp://www.blogger.com/profile/01948075949080934517noreply@blogger.com2tag:blogger.com,1999:blog-3550429348609609779.post-19951457657977029682008-12-14T18:00:00.000-08:002008-12-14T10:44:13.413-08:00Using TDD and Resharper to Learn Something New<span style="font-family:georgia;">This week, I have been working on building RSS feeds from objects in our domain model. I am using </span><a style="font-family: georgia;" href="http://msdn.microsoft.com/en-us/library/system.servicemodel.syndication.aspx">System.ServiceModel.Syndication</a><span style="font-family:georgia;"> to do the RSS/Atom formatting, so all I needed to worry about is the mapping between domain and the SyndicationItem.</span><br /><br /><span style="font-family:georgia;">Until recently I would have used XML (along with all its angle bracket evilness) to achieve this. However, I am becoming increasingly disillusioned with using XML for configuration because of the difficulty in testing and reading it. So, having been inspired by </span><a style="font-family: georgia;" href="http://code.google.com/p/fluent-nhibernate/">Fluent NHibernate</a><span style="font-family:georgia;"> and the fluent configuration of </span><a style="font-family: georgia;" href="http://msdn.microsoft.com/en-us/library/dd203217.aspx">Unity</a><span style="font-family:georgia;">, I decided that I would do the mapping using a fluent style. I was aiming for an API that would let me do something like:</span><br /><pre><span style="font-size:85%;"><br /> var doc = Repository.FetchDocument(someDocId);<br /><br /> var map = new SyndicationItemMapping<br /> {<br /> Title = doc => doc.Filename,<br /> Summary = doc => doc.Body.Substring(0,100),<br /> Content = doc => doc.Body, <br /> Copyright = doc => "(c) 2008. All rights reserved"<br /> };<br /><br /> var syndicationItem = map.From(doc);<br /></span></pre><br /><span style=";font-family:georgia;font-size:100%;" >I haven't done enough functional programming yet for all the concepts to have fully gelled in my head. I'm quite happy writing lamba expressions but I still struggle with the syntax for the Action<T> and Func<T> delegates that consume them. I knew (or thought I knew) that I was in for a tough couple of hours.<br /><br />TDD teaches us that when we get stuck like this we should write a test. I knew the kind of API I wanted, so it took me just a few moments to compose a test:</span><pre><span style="font-size:85%;"><br /> [Test]<br /> public void MapsTitleFromAnEntity()<br /> {<br /> var entity = new MockEntity { Name = "entity name"};<br /> var mapper = new SyndicationItemMapper<MockEntity><br /> {<br /> Title = entity => entity.Name<br /> };<br /> var syndicationItem = mapper.From<MockEntity>(entity);<br /> Assert.That(syndicationItem.Title, Is.EqualTo(entity.Name));<br /> }<br /></span></pre><span style="font-size:100%;">This is where the magic of <a href="http://www.jetbrains.com/resharper/index.html">ReSharper</a> kicked in. A couple of [Alt]+[Enter]'s in the right places generated the code for my SyndicationItemMapper class in a matter of seconds:<br /><pre><span style="font-size:85%;"><br /> public class SyndicationItemMapper<T><br /> {<br /> public Func<T> string Title { get; set;}<br /><br /> public SyndicationItem From(T entity)<br /> {<br /> throw new NotImplementedException();<br /> }<br /> }<br /></span></pre>So within a matter of about ten minutes, I had the outline of my implementation and know immediately how I was going to progress. I then completed the implementation for that test and added a few more tests with their implementations. In just over an hour I had built the entire mapping.<br /><br />Now the point of this post, is not to show how easy it was to build fluent interfaces (although when I compare the time this took compared to all the time it would have take me to build all the XML wotsits I'd have needed, its really quite impressive). No, the point is how TDD helped me to quickly learn some syntax I was unfamiliar with.<br /><br />Before TDD I would probably have written a [button 1] test harness and then spent hours floundering around trying to find the correct solution (and may well not of). But with the test case I had some solid syntax to aim for and could get the implementation within a couple of hours. Add in the power of Resharper and I was able to get the basic implementation done in a matter of minutes.<br /></span>Richard Naglehttp://www.blogger.com/profile/01948075949080934517noreply@blogger.com0