From the software development trenches
Agile Estimation using Risk Management Techniques
10 October 08 01:48 PM | cjlotz | with no comments

James Shore has published an excellent 2 part series of articles covering agile planning through using risk management practices to make solid commitments.   The articles show how to use Risk Multipliers to account for common risks such as turnover, changing requirements, work disruption and illustrates the techniques advocated through using 2 pseudo projects.  Start with Part 1 that lays the foundation and paints the "all-goes-well" scenario and then continue onto Part 2 that covers the scenario I think most of us are facing on a day-to-day basis.  Enjoy.

Filed under:
10 Keys to Successful Scrum Adoption
03 October 08 08:53 AM | cjlotz | with no comments

Having driven the adoption of Scrum during the last few months at our company, I'm constantly looking for ways to improve on the process as we are still experiencing some growing pains.  Construx (CEO: Steve McConnell of Code Complete fame) has recently published a new set of white papers covering some excellent topics.  One of the white papers is titled: "10 Keys to Successful Scrum Adoption" and I found it a really excellent read with some great best practices and pointers that will help you to avoid some of the pitfalls of adopting Scrum.  Go ahead and read it - requires you to register, but registration is free.

Filed under:
SDLC Progress
01 September 08 08:07 PM | cjlotz | 2 comment(s)

I've been spending the last month or two getting the SDLC procedures and infrastructure in place for the Silverlight release of our company's Enterprise Physical Asset Management system.  We were already using Team Foundation Source Control but wanted to adopt SCRUM as our development methodology and improve on some of our development practices such as using Continuous Integration, Test Driven Development, better Work Item Management and enhanced quality through Code Reviews, Check-in procedures and the selective use of Code Metrics. 

We have just completed our first 2 week sprint and the team felt that the processes and tooling worked quite well and enjoyed most of the new structure and discipline introduced.  In our retrospective we identified some process impediments that we want to improve on going forward. In this post I will highlight some of the processes and tooling we are using.

Work Item Management

We are using Conchango's SCRUM for Team System template to assist us with Work Item Management.  The Conchango template and the associated process guidance provides a good starting point.  I highly recommend taking a look at the new Conchango Task Board application to make the daily management of your Product and Sprint Backlog items a breeze.  The task board provides a very nice GUI for managing the essential fields of the work items as well as the state transitions.  The software is currently in Beta2 and still contains one or two frustrating bugs.

Conchango Task Board

Code Reviews

As mentioned in my previous post on code reviews, we are using a lightweight code review process that suites the distributed nature of our team.  We do reviews after all the development tasks for a PBI (business feature) has been completed.  The development tasks are only allowed to move into the Done state once the review has been completed.  The review process is also quite focused as we know all checked-in code adheres to a rigorous check-in procedure.  We also try and automate a lot of the standards compliance checking through the use of tools like FxCop and NDepend.

Check-in Procedure

We try to follow quite a rigorous process for check-in of our code into TFSC.  This idea is to try and ensure a continuous level of quality for the code being committed.  Here are the steps that all code needs to adhere to:

  1. Code has been integrated with close to the latest version of the code in the TFSC.
  2. Code has been formatted according to our company's ReSharper Cleanup Profile.  This ensures that all code uses the same C# layout structure and formatting standards.
  3. Code compiles without warnings in both Debug and Release mode.
  4. Code adheres to our coding standards document.  Where possible we try and automate the checking through the use of FxCop and NDepend CQL queries.
  5. No ReSharper code analysis violations.  Any violation needs to be identified and agreed upon.
  6. No FxCop violations.  Any violation needs to be identified and agreed upon.
  7. All unit tests run through successfully in your private workspace.  We've just introduced code coverage and we'll probably include some minimum level of coverage for the future.
  8. All functional tests cases run through successfully in your private workspace.  We are in the process of automating our acceptance tests as and we hope to have this running within the next sprint or tow.

Continuous Integration

As I previously mentioned we use the excellent TeamCity for our CI server.  We are very happy with the results.  We have integrated NUnit, NCover, FxCop and NDepend into 3 separate builds configurations:

  1. Continuous - Build that currently runs every 2 hours to compile the code and run the NUnit tests.
  2. Daily - Build that runs every evening at 22:00 to compile the code, product documentation and build the installer.
  3. Metrics - Build that runs every evening at 22:30 to run FxCop, NCover and NDepend to generate the metrics for the day's development.

We have just started using the Microsoft Silverlight Testing framework for our client side UI tests and the idea is to integrate this into the build process for the next sprint that starts tomorrow.  More on all of this at a later stage.

Code Reviews using TFS Tools
25 August 08 07:47 PM | cjlotz | 2 comment(s)

I've previously blogged about using code reviews as an effective way to minimize defects, improve code quality and keep code more maintainable.  In my new job I had to define a code review process that suited our development team as well as the Team Foundation Server toolset and the Conchango SCRUM for Team System process template we are using.  This post details what process and tooling we came up with.

Review Style

To improve on the cost-benefit factor of the reviews we opted for a lightweight code review process.  The aim was to get improved code quality but not incur the overhead of traditional meetings-based inspections.  Because of the distributed nature of our development team, we are using a flavour of the e-mail pass-around review style.  In a traditional email pass-around, the author or source code management system packages the code changes and sends an e-mail to the reviewers.  We decided to use the Code Review Sidekick of Attrice Corporation to get a consolidated list of code changes that have been checked into TFS.  We do not send an e-mail containing the changes but instead use a Code Review Sprint Backlog item to track and manage the review process.  More on this in the Review Process section.

Review Frequency

We do reviews after all the development tasks required to complete a piece of business functionality have been checked in. We discussed the issue of using shelving to prevent not reviewed code from being checked in, but the team felt that as we are following a quite rigorous process for check-in we can do the review at a later stage on the checked-in changes.  The developers working on completing their tasks are however not allowed to change the status of their tasks to Done.  The reviewer has the responsibility of signifying the work as completed when he/she has completed a successful review.  To make the review process as light as possible we also try to automate a lot of the coding standards and architectural standards through the use of tools like FxCop, ReSharper and NDepend.

Review Tooling

Although there are some CodePlex projects that provide support for customizing TFS to support code reviews and code review flows, we decided to steer away from using these solutions as they depend on creating custom work items and custom work item states.  We wanted to only use the default Conchango SCRUM for Team System process template.  Unfortunately the template doesn't contain a Ready for Review state for a Sprint Backlog item, but we decided to use the Ready For Test state to signify that a task is ready for review as we execute the testing as part of the check-in.

Review Procedure

As already mentioned, to manage and track the code review process and feedback, we create a special Code Review Sprint Backlog Item (SBI) associated with every Product Backlog item (PBI) during Sprint planning.  The author ensures that all the development SBI's for the PBI are in the Ready for Test status and have been checked in.  The author marks the Code Review SBI as Ready for Test and assigns it to the reviewer to request a review.  The reviewer gets notified of the new review work item assigned to him/her and uses the Code Review Sidekick tool to get a consolidated list of changesets with their associated files for the work completed.CodeReview_1

This presents the review with a list of the code changes that were made.CodeReview_2

When the reviewer right clicks on a file to review, he/she can have up to 3 options.CodeReview_3

The options imply the following:

  1. Compare With Previous (Not In View) – This will compare the versions of LogonController.cs in CS 6870 and CS 6721 to each other.  Use this option to see what has changed within the file as part of the complete development effort associated with the PBI work.
  2. Compare With Previous In View – This will compare the versions of the LogonController.cs in CS 6870 and CS 6869 to each other (only if > 1 change to same file).  Use this option to see what has changed within the file between the two changesets.
  3. Compare With Oldest in View - This will compare the versions of the LogonController.cs in CS 6870 and CS 6722 to each other (only if > 1 change to the same file).  Use this option to see what has changed between the first and last checkin for the same file.

The reviewer conducts the review and continuously updates the Work remaining on the Code Review SBI.  Any questions are clarified by the author through Skype/Interwise or verbal communication. The reviewer also adds any comments/notes to the Code Review SBI itself. After completing the review, the reviewer contacts the author to discuss the issues identified. The author and reviewer agrees upon what issues needs to be addressed.  Here we can have 2 possible outcomes:

  1. Small fixes - author quickly fixes these and checks in the changes
  2. Major fixes
    1. The reviewer assigns the Code Review SBI back to the author to make the relevant fixes.
    2. The author updates the Work Remaining of the relevant development SBI's to a value > 0 to indicate the effort required to make the fixes.  This shows up on the Sprint Burndown chart as an upward blip as the effort for the sprint increases due to the rework.
    3. The review process is repeated until the reviewer is satisfied

Finally, once the reviewer is satisfied, the reviewer changes the Code Review SBI status to Done and changes the status of the development SBI's to Done to signify that the PBI is completed.

.NET Continuous Integration Servers
01 August 08 07:19 AM | cjlotz | 2 comment(s)

It seems like I spend a lot of time on this blog talking about Continuous Integration smile_regular  Well, in my new job one of first my tasks was to setup a CI server.  Instead of using CruiseControl.NET again I decided to spend some time investigation other .NET alternatives.  The idea was to see whether there was not as easier way to setup the CI environment.  I've long wanted to investigate Team Foundation Build and I've also heard some great things about JetBrains TeamCity - the makers of my favourite IDE tool ReSharper!

I started out with TFBuild as it comes out-of-the-box with any Team Foundation Server setup. Setting up the build configuration was easy enough but I however soon ran into problems when wanting to integrate our NUnit test results.  After some research I discovered some workarounds for making it think that the NUnit test results were MSTest runs, but soon got discouraged with the nature of the work involved to get this work.  It seems that TFBuild is currently very much oriented towards supporting the default Microsoft toolset.  If this fits your development scenario, then look no further.

Putting TFBuild on ice, I moved onto TeamCity and was pleasantly surprised by how easy it was to get a basic build up and running.  The integrated NUnit support works great and the cool statistics graphs makes for some real pleasant viewing.

image

I'm also very impressed with the build portal site as it makes very effective use of AJAX to give you up-to-date information on what's happening with your builds.  After getting a basic continuous build in place, I moved onto trying to get a daily build working with TeamCity.  This turned out to bit a more challenging though.  Our daily build includes the versioning of the assemblies and it also labels the repository with the build number created.  Unfortunately TeamCity doesn't currently support the checkout-on-agent functionality for Team Foundation Server.  As TeamCity does not create a workspace on the build agent, you are not able to do these kinds of TFS source control related operations as part of your builds.  There is a feature request for adding this in the future (please vote for it), but for now you have to live with this limitation.

Having been impressed with the overall power of TeamCity I was not ready to give up on TeamCity yet and decided to see whether it was not possible to add the missing piece of functionality.  The idea was to let TeamCity invoke a custom MSBuild task on the build agent as part of the daily build to create a workspace, get the changes into the workspace and then also checkin and label the repository.  After some research and a night of development I was able to complete the MSBuild task and I'm happy to report that it is now working fine.

Overall I'm very impressed with the functionality provided by TeamCity  and we will be using this as our future .NET CI server.  The next version will include support for integrating FxCop results out-of-the box, but it is also easy enough to integrate external tools like FxCop, NCover and NDepend through adding the build outputs of these tools as artifacts to a build.  For more information on this have a look at the posts made by  Laurent Kempé.

Conventions for Generated and Shared Code
22 July 08 05:28 AM | cjlotz | 3 comment(s)

We had a discussion in our team about standards for generated and shared code files.  When talking about shared code, we are referring to sharing the same source file between different projects as in a GlobalAssemblyInfo.cs file that contains the AssemblyInfo attributes that are shared by the different projects in your solution.  We ended up agreeing to the following:

Generated Code

  1. Do use partial classes to separate the generated code from your own hand-written C# code. 
  2. Do put the generated code into its own separate .cs file, naming the file according to the logical part it plays, ie. Staff.cs and Staff.Validations.cs.  This is very nicely illustrated and adhered to by the designer generated code produced by Visual Studio these days. 
  3. Do group all generated code into a region,  e.g. #region "DataDictionary generated validation methods". This makes it clear that the code has been generated and it also has the side benefit of allowing tools like ReSharper 4.0 to ignore Code Analysis on these regions as you can tell it to ignore regions that are marked with specific tags.  Of course the idea is to generate clean code that does not produce these warnings in the first place.
  4. Consider making use of the <DependentUpon> tag in the .csproj file to mark the generated .cs file as a child element of the non-generated .cs file (or vice-versa) in the Visual Studio solution explorer, e.g.

Copy Code
<Compile Include="Staff.Validation.cs"> <DependentUpon>Staff.cs</DependentUpon> </Compile>

Shared Code

  1. Do not append a suffix to a shared code file, e.g.  AssemblyInfo.Shared.cs.
  2. Do use the "Add as Link" functionality within Visual Studio to add the file to the different projects that are using it.
  3. Do create a separate folder structure to store the shared files in source control, e.g. MyProject\Main\Source\Shared
  4. Consider creating a solution folder within Visual Studio to group the shared files.

What conventions are you using to manage your generated and shared code files?

AnkhSVN 2.0 Released!
11 July 08 01:25 PM | cjlotz | 1 comment(s)

Just a short post to make people, who are using Subversion, aware of the v2.0 release of AnkSVN - "the open source Subversion plugin for Visual Studio".  The biggest new feature in my mind is that it has been rewritten to run as a VS SCC plugin.  Screenshots are available here.  I've been a happy VisualSVN user up till now but this new release may just convince me to make a switch.  Great work!  clap

Filed under:
No news good news?
08 July 08 03:13 PM | cjlotz | with no comments

As the blog post says, I haven't been too active on the blogging front for the past 2-3 months.  This has been mostly due to the career move I made to Pragma Products beginning of June.  Having been at the company now for just more than a month I am very happy with the move.  The company, people and the opportunities going forward are great.  Moving from a big corporate environment into a smaller company has been a very positive move for me.  It is great to be able to add immediate value to an environment!  We are embarking on an exciting re-write of the company's core enterprise asset management application.  We will be utilizing new and exciting technologies like Silverlight 2 and WCF so expect some future blog content on this as we get to know the technologies more intimately.  The first release is for a big international customer and we will have to support multiple languages like Chinese and German so I guess we will be taking the Turkey test smile_wink 

Currently I'm spending some time on improving the SDLC.  We are using Team Foundation Server 2008 and we want to use the Conchango Scrum for Team System process template.  I haven't worked directly with Scrum before, but having had some experience with the Open Unified Process and Rational Unified Process the concepts are familiar.  I'll miss working with Subversion though smile_sad  I know about SvnBridge but to me that is fighting your tools in stead of trying to work in the way they prescribe.  I'm looking forward to figuring out how to implement Continuous Integration using Team Build to see how it matches up with the process I documented using open source tools.

One thing that I am still getting used to in the new environment is the fact that more than half of the team members work from home for large portions of the week.  This makes it quite challenging for a newcomer to get to know everybody.  We have a weekly team meeting that is held mostly at our offices and I met most of the team through these meetings.  Needless to say it has taken some time for me to get to know everybody.  Fortunately the planning sessions we had last week was mandatory attendance and I was able to interact a bit more with them.  The team uses Skype and Interwise for video conferencing to keep in touch.  After being a bit skeptical at first, the technology works quite well.  I'm however still a bit cautious about the whole distributed agile development team so I might blog about my experiences of this process going forward as well.

Till later...

Filed under: ,
ReSharper 4.0 Released!
10 June 08 05:50 AM | cjlotz | with no comments

ReSharper 4.0 is finally released!!  See the Features and What's New.

Filed under:
Steve McConell on Software's Classic Mistakes - 2008
14 May 08 09:15 AM | cjlotz | with no comments

Steve McConnell, author of the excellent Code Complete, has published an updated version of the Software Classic Mistakes he identified in his book Rapid Development published in 1996.  The idea was to see what the industry is like 12 years later.  Read more about it here.

Filed under:
NDepend
12 May 08 09:24 AM | cjlotz | with no comments

I've said it before and I want to say it again.  If you are serious about code quality and you want to use static code analysis to help you improve on your code's quality, you just have to look at getting yourself a NDepend license.  Patrick Smacchia, the developer of NDepend, has just posted another excellent article that highlights some of the major areas where NDepend can help you pinpoint problematic areas in your code base.  Because of NDepend's excellent Code Query Language, you are able to write your own dynamic active code conventions that fit your environment and architecture of the system you are developing.  In the article Patrick gives some excellent examples of some of the common CQL queries that you can use to prevent incorrect coupling, layering etc. and ways to ensure the correct evolution of your code.

So don't delay - get yourself a license now and don't forget to fit NDepend into your continuous integration process.  Use it together with FxCop and you will go a long way towards enhancing the quality of the code you are delivering.

Filed under:
Career move
30 April 08 03:23 PM | cjlotz | 3 comment(s)

May will be my last month working as a .NET Technology Consultant at Sanlam.  I have accepted an exciting position as Software Architect at Pragma Products where I will join the team beginning of June 2008 to work on the next generation of their software products.  I'm super excited about the company, challenges and the people I will be working with and for the opportunity to finally work in an environment where I can concentrate on using only .NET to build great software.

Filed under:
In Search of Content Collaboration Tools
29 April 08 02:14 PM | cjlotz | 2 comment(s)

image We went through an exercise in the past month or so of trying to select the best platform to use in our company to engage the development communities using mediums like forums/blogs and for managing the content surrounding our development methodology, coding standards and processes through using a wiki.  

We are currently using two different open source products - MoinMoin as a wiki and phpBB for developer related forums.  These products work fine, but the idea was to see whether there are better alternatives available and whether there is not a single product offering that combines wiki/forum functionality with additional collaboration mediums like blogs to create a single source of information going forward.  Having said this, the most important part of the solution for us is the wiki and as such the platform of choice decision was heavily skewed towards the wiki support provided by the solution. 

As the enterprise development landscape in my company is unfortunately mostly geared towards Java, I had to identify and "fight for" different Microsoft solutions that supported these requirements.

ASP.NET Wiki Engines

The first solution that came to mind was Windows SharePoint Services (WSS) 3.0. At the time I was not allowed to investigate MOSS as the product had to be free.  In addition to WSS 3.0, I also previously used two other ASP.NET wiki engines (Perspective Wiki and ScrewTurn Wiki) for managing project related content.  I took these into account as well.

The Wiki functionality provided by WSS 3.0 is IMHO still a bit immature.  I think this has to be expected from a version 1 feature (wiki's are new to WSS 3.0) and by a platform that tries to address the complete content management picture, i.e. support for forums, blogs, projects etc.  This "weakness" is also the biggest strength of WSS 3.0 as it provides a consolidated platform and experience that makes it quite easy to setup a content management solution that includes forums, blogs, projects and much, much more.  The platform itself is extensible as reflected by the ongoing efforts by the community to plug some of the gaps through the Community Kit for SharePoint.  I was quite impressed by the functionality provided by the Enhanced Blog Edition as it provided in my mind most of the missing pieces for a blogging platform, but unfortunately the Enhanced Wiki Edition is still in early days and still missing quite a few important pieces.  The lack of good Wiki support therefore unfortunately ruled WSS out of the picture for us.

Both Perspective and ScrewTurn, as dedicated wiki engines, provide better support for Wiki functionality than WSS 3.0.  Perspective v1 was the first wiki engine I used 2 years back and the results were not too bad.  It has a WYSIWIG editor and for simple scenarios it can be quite effective.  The current v3 Alpha includes a complete overhaul of the Wiki engine with lots of new and exciting features and it seems quite promising.  My only concern is that progress is very slow with the wiki being developed by a single developer. 

These days it seems like ScrewTurn wiki has a lot of momentum behind it as evident through having been declared the winner of Jeff Atwood's donate $5000 to .NET Open Source project.  I'm using ScrewTurn wiki daily and the wiki is frequently being updated with bug fixes and new releases.  There is also an extensive set of community plugins available that add additional missing functionality like AD integration etc.  It unfortunately does not currently support WYSIWYG editing and for us that is a show stopper seeing that our users want to copy/paste content from Word documents and use general RTF editing capabilities.

Final Choice

With no strong MS candidate to bring to the table, I was forced (kicking and screaming smile_wink) to accept a non MS commercial offering!   We opted to buy a Confluence license and I must say that I am very happy with our choice.  Confluence really provides everything you need in terms of a Wiki engine and the price tag is in my opinion quite reasonable given all the features that you get.  The only thing missing from Confluence is the lack of support for forums.  For this I think we'll stick with phpBB and connect the two using an include page macro.

It would be interesting to know whether there are any MS technology based teams that are using anything besides WSS/MOSS/Team System for content collaboration.  What other tools are in your opinion worth looking at?

Filed under: ,
UI Prototyping Tools
08 April 08 09:28 AM | cjlotz | 3 comment(s)

Jeff Atwood's post about UI-First Software Development came just about at the right time as I was looking for some tooling to assist me with a quick prototype that I had to create for a reference application we are building.  For the purposes of this application we needed something more formal than paper prototypes and the tooling should be available for use in different projects within our company.

My favourite UI prototyping tool is MockupScreens.  It is an inexpensive tool that allows you to quickly and effectively create screen mockups using the most common windows controls with sample data and screen navigation included.  You can export the screens as images or as HTML pages with screen navigation to demo to your stakeholders.  There are certainly more professional and expensive prototyping tools available (GUI Design Studio comes to mind), but for simple, yet effective mockups, MockupScreens IMHO gives me the most value for money.  Here is a screen shot of a mockup screen created with MockupScreens.

image

Jeff also links to using PowerPoint 2007 as a wireframe prototyping tool.  I haven't considered using PowerPoint as an option before and I was more interested in the GUUUI Web Prototyping Tools for Visio that some of his readers recommended.  As Visio is already licensed within my company we would not have to buy any additional licenses.  I decided to give it bash.

I must say I was pleasantly surprised by the functionality provided by these templates.  It allows you to draw up a site master that includes the common layout and navigation for your site.  You can then use this master page as the background for your other pages very much like the master page support of ASP.NET.   The sketchy interface widgets also look great and conveys the message of this being a prototype very clearly.

Here is a sample master page for a book store web site:

MasterPage

Here is Browse Catalogue mockup screen based on this master:

BrowseCatalogue

You can easily link up pages together using the hyperlink functionality of Visio and also publish the wireframe to HTML that will include the navigation via the hyperlinks.  It takes a bit longer to create than MockupScreens, but the master page feature is excellent as it allows me to change the common layout in one place and have it correctly reflect in all the other pages!  Excellent stuff! smile_shades

What other tools would you recommend for doing UI Prototyping?

Filed under:
Null Object Pattern
03 April 08 11:01 AM | cjlotz | with no comments

I've been going through some chapters of Agile Principles, Patterns and Practices in C# (which I highly recommend) and I came across a nice trick when implementing the Null Object Pattern that I wanted to share. 

Background

For those new to the Null Object Pattern, I quote from Wikipedia:

In most object-oriented languages, such as Java, references may be null. These references need to be checked to ensure they are not null before invoking any methods, because you can't invoke anything on a null reference. This tends to make code less readable. Instead of using a null reference to convey absence of an object (for instance, a non-existent customer), you use an object which implements the expected interface, but whose method body is empty. The advantage of this approach over a working default implementation, is that a Null Object is very predictable and has no side effects: it does nothing.

It can also be used to act as a stub for testing, if a certain feature, such as a database, is not available for testing.

Martin Fowler also refers to the Null Object Pattern as the Special Case pattern in his Catalog of Patterns of Enterprise Application Architecture.

Implementation

In the application I am currently building, a product catalog can be searched based on price ranges.  For this I created a PriceRangeItem class that is contained within a list provided by a PriceRange class.  The idea is to bind the UI against the list to provide a filter for the products based on the price range.  The list needs to include an "empty choice" item that, when selected, should not affect the search results.  This "empty choice" item is an ideal candidate for a Null Object. 

Here is my implementation:

1 public class PriceRangeItem 2 { 3 private readonly int rangeId; 4 private readonly double rangeFrom; 5 private readonly double rangeThru; 6 private readonly string rangeText; 7 8 public static readonly PriceRangeItem Null = new NullPriceRangeItem(0, double.MinValue, double.MaxValue, string.Empty); 9 10 #region Constructors + Destructors 11 12 public PriceRangeItem(int rangeId, double rangeFrom, double rangeThru, string rangeText) 13 { 14 this.rangeId = rangeId; 15 this.rangeFrom = rangeFrom; 16 this.rangeThru = rangeThru; 17 this.rangeText = rangeText; 18 } 19 20 #endregion 21 22 #region Public Members 23 24 public int RangeId 25 { 26 get { return rangeId; } 27 } 28 29 public double RangeFrom 30 { 31 get { return rangeFrom; } 32 } 33 34 public double RangeThru 35 { 36 get { return rangeThru; } 37 } 38 39 public string RangeText 40 { 41 get { return rangeText; } 42 } 43 44 #endregion 45 46 #region NullPriceRangeItem Class 47 48 private class NullPriceRangeItem : PriceRangeItem 49 { 50 public NullPriceRangeItem(int rangeId, double rangeFrom, double rangeThru, string rangeText) 51 : base(rangeId, rangeFrom, rangeThru, rangeText) 52 { 53 } 54 } 55 56 #endregion 57 }

The trick is to declare NullPriceRangeItem as a nested, private class to prevent external instances of the class being created.  A public static field called Null is then added to PriceRangeItem to expose the single instance of the Null Object that should exist for the application (see line 8).  Other application code can now easily refer to this instance by using code like:

1 if (SelectedPriceRange != PriceRangeItem.Null) 2 { 3 ... 4 } 5

For completeness sake, here is the code for PriceRange class that shows the Null Object being added to the list of price ranges:

1 public static class PriceRange 2 { 3 private static readonly List<PriceRangeItem> list = null; 4 private const string RangeText = "{0:C} - {1:C}"; 5 6 static PriceRange() 7 { 8 list = new List<PriceRangeItem>(); 9 10 list.Add(PriceRangeItem.Null); 11 list.Add(new PriceRangeItem(1, 0, 50, string.Format(RangeText, 0, 50))); 12 list.Add(new PriceRangeItem(2, 51, 100, string.Format(RangeText, 51, 100))); 13 list.Add(new PriceRangeItem(3, 101, 250, string.Format(RangeText, 101, 250))); 14 list.Add(new PriceRangeItem(4, 251, 1000, string.Format(RangeText, 251, 1000))); 15 list.Add(new PriceRangeItem(5, 1001, 2000, string.Format(RangeText, 1001, 2000))); 16 list.Add(new PriceRangeItem(6, 2001, 10000, string.Format(RangeText, 2001, 10000))); 17 } 18 19 public static List<PriceRangeItem> All 20 { 21 get { return list; } 22 } 23 24 public static List<PriceRangeItem> InRange(double rangeFrom, double rangeThru) 25 { 26 return All.FindAll(delegate(PriceRangeItem item) 27 { 28 return item.RangeFrom >= rangeFrom && item.RangeThru <= rangeThru; 29 }); 30 } 31 } 32

Because the ranges with which the NullPriceRangeItem was created with are the minimum and maximum values for a double, you can safely enough use the list without worrying about the NullPriceRangeItem limiting the search results.

Filed under:
More Posts Next page »