Everyone knows (or would know if they'd read Code Complete) that 'magic numbers' are a bad thing in your code. Enumerated types, or Enums in .NET, are a great way to avoid such magic numbers. For instance, let's say I have a content management system which has articles whose state can vary between Draft, Editing, and Production. I could simply use 1, 2, and 3 for these states and remember what each stands for, but that's going to be really hard to look at six months later when I revisit the code (or if someone else has to read it). In languages without enumerated types, named constants would be a step in the right direction, but truly enums are much more powerful because they allow me to limit the allowable values of parameters to only valid values. For instance, I might have a method for updating the status of an article, called UpdateStatus(), which takes an integer articleId and an integer statusId. There's nothing to prevent me from sending a -5 or a 300 to the statusId, which of course would not be valid status numbers, but are perfectly acceptable integers. If instead I define the method so that it accepts an integer articleId and an ArticleStatus statusId, where ArticleStatus is an enumerated type, I'm assured that only valid values can be passed to that method (the compiler will enforce that).
Now, it's frequently the case that the database will contain so-called lookup tables, or tables whose sole purpose is to provide some information about another table through a foreign key. In the above example, my Article table would likely have an ArticleStatusId which would be a foreign key to the ArticleStatus table. ArticleStatus would simply have two columns, ArticleStatusId and Name, and would be considered a lookup column in this case. These provide similar usefulness to enums, but at the database level. By using a foreign key to this table instead of just an integer column without any constraints, I've ensured that only valid status ids can exist in my Article table. I can also use the lookup table's data to populate dropdownlists in the UI to constrain the user's selection at that level.
Since they serve similar purposes, it would be great if lookup tables could be automatically converted into enumerated types so that developers could get compile-time strong type checking in their applications. With Yukon's integration of .NET, we may be a step closer to this, but I'm not aware of any such feature coming any time soon. So what often happens is enums and lookup tables are both used, and at some point they get out of synch with one another. An additional status type, e.g. Archived, is added to the ArticleStatus lookup table in the database, but the enum is not updated (which requires the code to be recompiled). This kind of thing will not cause any errors immediately, but it will come back to bite you at some point when you try to use the new value through your compiled application. Some way of notifying you that the database's values had changed so that you knew to update and recompile your code is needed.
Although probably not the ideal solution to this problem, one solution I've devised is to write an enum-to-lookuptable checking unit test, using NUnit. This test passes if the number of rows in the lookup table matches the number of items in the enum, and if each item in the lookup table has a matching value and named item in the enumeration. An example of the test is shown here (note that this uses the Microsoft Data Access Application Block in addition to NUnit 2.1):
public void EnumMatchesTableData()
Type enumType = typeof(AspAlliance.Data.Cms.ArticleStatus);
DataTable dt = SqlHelper.ExecuteDataset(AspAlliance.Data.Cms.SqlServer.Configuration.Current.ConnectionString,
"SELECT * FROM ArticleStatus ORDER BY ArticleStatusID").Tables;
Assertion.AssertEquals("Enum count does not match database count.",
foreach(DataRow row in dt.Rows)
int id = Int32.Parse(row["ArticleStatusID"].ToString());
Assertion.AssertEquals(row["Name"].ToString().Replace(" ", ""), Enum.GetName(enumType, id));
In a follow-up to my caching best practices article, this one shows how to encapsulate the best practices into a helper class.
Creating a Cache Configuration Object for ASP.NET
Summary: Learn how the CacheConfig helper class can improve caching policies across an ASP.NET application, improve reuse of cached data, and significantly reduce lines-of-code to implement caching using best practices. This article builds upon the ASP.NET Caching: Techniques and Best Practices article.
From Charlie Poole on the TDD List:
The final release of NUnit 2.1 is now available for download at
This release has a number of improvements, most notably that it will
run under version 1.0 of the .NET framework as installed. It includes
separate configuration files for use with .NET versions 1.0 and 1.1.
Both configs are copied and the correct version for the current system
is installed ready for use.
NUnit 2.1 can run tests built against NUnit 2.0. A sample config file
for use in this situation is included.
Substantial changes have been made to error and exception reporting.
The exception type is listed along with all inner exceptions. In the
console runner, this includes a full stacktrace. The full trace for
exceptions that are caught by the GUI runner is now available under
the Tools | Exception Details... menu item.
This release has been verified to install and run under Windows 98.
The feature of watching for changes in the assemblies and reloading
them automatically is disabled in this environment. We haven't tested
under Windows ME, but believe it will work in that environment as well.
Unfortunately, at this time SourceForge is down and the URL for NUnit 404s, but hopefully that is only temporary.