June 21, 2004

Gmail Giveaway

OK, readers - similar to the contest at , I'm giving away a Gmail account to the funniest joke or story that gets posted here. Of course, this is 100% subjective but my redership is modest, so you have a great chance of winning the account. I alone will choose the winner based on how hard/long you make me laugh. Thank Sergio for the inspiration. If you haven't checked out , you're missing out on a real gem - one of the best blogs on the net. Go check it out!

Posted by Christian at 06:49 AM | |

June 15, 2004

Sam Gentile on Unit Testing

Sam Gentile states it perfectly . Microsoft's trying to skimp on including the Unit Testing tools in every Whidbey version, which makes zero sense to me. Unit Testing is the more sophisticated cousin of Debug.Assert. We wouldn't reserve that for a special version, would we?!

Posted by Christian at 03:33 PM | |

Decorating Proxy Pattern for Implementation of Caching

I came up with this design pattern variation a while back which is the synthesis of Proxy and Decorator. It’s not really a brand new pattern, but it varies from the normal pattern of usage for Decorator and Proxy. Feedback welcome.

Decorating Proxy

A hybrid of Proxy and .

“The proxy pattern makes the clients of a component communicate with a representative rather than to the component itself. Introducing such a placeholder can serve many purposes, including enhanced efficiency, easier access and protection from unauthorized access.”

The Decorator pattern serves to attach “additional responsibilities to an object dynamically. Decorators provide a flexible alternative to sub-classing for extending functionality.”

Uses:

One use of this pattern is to implement caching. One way of doing this is to define a shared interface for both the object and the proxy, and to define a constructor for the proxy which accepts a reference to the DAL object. By defining a constructor which accepts a parameter of the same base type, we are in effect blurring the line between Proxy and Decorator.

Example:

public interface IHotelGateway
{
  IHotel GetHotel(string Destination, string HotelCode);
}
public class HotelCacheGateway: IHotelGateway
{
    private IHotelGateway store = null;
    public HotelCacheGateway(IHotelGateway Store)
    {
        store = Store;
    }
    public IHotel GetHotel(string Destination, string HotelCode)
    {    
        IHotel hotel = Cache[GenerateKey(Destination, HotelCode)] as IHotel;
        if (null != hotel) return hotel;
        hotel = store.GetHotel(Destination, HotelCode);
        if (null != hotel) Cache[GenerateKey(Destination, HotelCode)] = hotel;
        return hotel;
    }
}

Then, instead of asking the Data Access Layer (DAL) for an object directly, the client code can ask the Decorating Proxy which will either
retrieve the object from a cache or delegate the call to the DAL.

IHotelGateway proxy = null, dal = null;
dal = new SqlHotelGateway(connection_string);
proxy = new HotelCacheGateway(dal);
IHotel hotel = proxy.GetHotel(destination, hotelcode);

Or, better still, the creation of the Proxy and DAL can be encapsulated in a Factory Method which keeps the client from having to even know about the Proxy.

public class HotelGatewayFactory
{
    private const string ConnectionString = "...";
    public static IHotelGateway Create()
    {
        IHotelGateway proxy = null, dal = null;
        dal = new SqlHotelGateway(ConnectionString);
        proxy = new HotelCacheGateway(dal);
        return proxy;
    }
}

IHotelGateway gateway = HotelGatewayFactory.Create();
IHotel hotel = gateway.GetHotel(destination, hotelcode);

Benefits:

  • Layering (separation of concerns). Client code does not need to concern itself with caching and can focus on what it needs to do with the object
  • Maintainability. It becomes trivial to add/remove the caching functionality because the interface of the cache is the same as the DAL.
  • Simplicity. Designing a caching layer doesn’t require thinking about interface (since it’s already defined) allowing the developer to focus on the most efficient implementation

Extended example:

using System;
using System.Web;
using System.Web.Caching;
// minimal implementation - a better implementation would allow for dependency and expiration control
public class CacheManager 
{       
    private static CacheManager singleton = null;       
    private CacheManager()
    {
                
    }   
    public static CacheManager Instance 
    {   
        get 
        { 
            if (null == singleton) singleton = new CacheManager(); 
            return singleton;
        }
    }
   public static void SetItem(string key, object value)
   {
       HttpContext.Current.Cache[key] = value;
    }   
    public static object GetItem(string key)
    {
        return HttpContext.Current.Cache[key];
    }   
}

using System;
public interface IHotelGateway
{
  IHotel GetHotel(string Destination, string HotelCode);
}

using System; /* -- note lack of dependency on System.Web.Caching -- */
public class HotelCacheGateway: IHotelGateway
{
    private IHotelGateway store = null;
    public HotelCacheGateway(IHotelGateway Store)
    {
        store = Store;
    }
    public IHotel GetHotel(string Destination, string HotelCode)
    {    
        IHotel hotel = CacheManager.Instance.GetItem(GenerateKey(Destination, HotelCode)) as IHotel;
        if (null != hotel) return hotel;
        hotel = store.GetHotel(Destination, HotelCode);
        if (null != hotel) CacheManager.Instance.SetItem(GenerateKey(Destination, HotelCode), hotel);
        return hotel;
    }    
    private string GenerateKey(string Destination, string HotelCode)
    {
        return string.Format("Hotel:{1}-{0}", Destination, HotelCode);
    }
}

using System;
using System.Data;
using System.Data.SqlClient;

public class SqlHotelGateway: IHotelGateway
{
    private string ConnectionString = null;
    public SqlHotelGateway(string ConnString)
    {
        ConnectionString = ConnString;
    }
    public IHotel GetHotel(string Destination, string HotelCode)
    {    
        IHotel hotel = new Hotel(Destination, HotelCode);
        using (SqlConnection db = new SqlConnection(ConnectionString))
        {
            SqlCommand sp = new SqlCommand(db);
            sp.CommandType = CommandType.StoredProcedure;
            sp.CommandText = "usp_GetHotel";
            sp.Parameters.Add(new SqlParameter("", Destination));
            sp.Parameters.Add(new SqlParameter("", HotelCode));
            using (SqlDataReader rdr = sp.ExecuteReader())
            {
                while (rdr.Read())
                {
                    hotel.Description = rdr["Description"].ToString();
                    hotel.SetContact(rdr["ContactName"].ToString(), rdr["ContactEmail"].ToString());
                    hotel.RoomCount = DBNull.Value == rdr["NumberOfRooms"] ? -1 : int.Parse(rdr["NumberOfRooms"]);
                }
            }
        }        
        return hotel;
    }    
}

using System;
public class HotelGatewayFactory
{
    private const string ConnectionString = "...";
    public static IHotelGateway Create()
    {
        IHotelGateway proxy = null, dal = null;
        dal = new SqlHotelGateway(ConnectionString);
        proxy = new HotelCacheGateway(dal);
        return proxy;
    }
}

// Client code 
IHotelGateway gateway = HotelGatewayFactory.Create();
IHotel hotel = gateway.GetHotel(destination, hotelcode);
The main thing to notice about the code above is that the dependencies on specific parts of the framework (like System.Web and System.Data) are limited only to those objects that need to work with them directly. This makes swapping out implementations easier because the dependenices are localized. Changing the CacheManager to work with the file system would not affect client code one bit. Likewise, a migration to an Oracle backend would only affect one class.

Of course, this also assumes certain things about how you package the classes into assemblies. For instance, if you package these classes into one monolithic assembly, then while most code maintenance benefits remain, you will force a recompilation every time you add a new Decorating Proxy that the Factory class needs to know about. This pattern forces you to separate the Factory into a separate assembly so that you minimize the impact of changes. Of course, having an assembly with one class — especially such a small one — is lame, so I would advocate packaging all or several factory classes together into an assembly that, in essence, defines the API for the application. If this sounds familiar, it’s probably because it sounds a lot like Martin Fowler’s Service Layer pattern from , albeit at a lower level. Service Layer is more of a UI layer pattern. This pattern is more of a Data Access Service Layer which defines a common interface for accessing data without requiring the caller to care about implementation details like whether or not the data is being retrieved from a cache or the backing data store.

Posted by Christian at 01:02 PM | |

June 14, 2004

Got Gmail?

I do! :) Thanks, !

Posted by Christian at 01:56 PM | |

C# Needs Static Interface Members

For those who were subscribed to my old blog, this is a bit of a rehashing so forgive me. I'm in the middle of building a Web Service where I have to return some information about hotels. The data is stored in SQL Server, but I'm focusing on getting the messaging interface done before delving into the actual data retrieval. The web service has the requirement that it must conform exactly to the interface of an existing web service from one of our business partners. That way, our partners can go to the web.config file and swap out their implementation for ours. Turns out the syntax and semantics of their messages are pretty quirky (read crappy). For example, rather than making use of the SOAP Fault facility, their message format defines an node that contains and elements that must contain the data from System.Exception::Message and System.Exception::StackTrace, respectively (No, I'm not kidding).

Anyway, I digress. The point is that I want to test that the message structure returned from the web service conforms to their specifications under normal conditions and exception conditions. I know I only need to pass the SQL stored procedure (which I haven't written yet) two parameters: DestinationCode and HotelCode. What I really want to do is to create an interface that defines the operation like so:

public interface IHotelGateway { XPathNavigator GetHotelDetails(string DestinationCode, string HotelCode); }

This way, I can build myself a mock implementation of the IHotelGateway interface that returns some sample data right away, letting me concentrate on getting the interface right before I worry about the implementation details. This has the benefit of allowing the business partner to test their client against my web service without having to wait for me to do all the wiring against the database. The next problem I anticipate is that there will be several places in my local code that look like this:


IHotelGateway dal = new MockHotelGateway();

So it would be best to refactor this into a private member of the web service:

private IHotelGateway dal = new MockHotelGateway();

But being a lazy programmer, I don't want to have to recompile my application just to change the implementation (MockHotelGateway vs SqlHotelGateway). So I really want to have Factory object create the IHotelGateway for me based on certain conditions (Debug vs. Release for example). So I want to create:

public interface IHotelGatewayFactory
{
static IHotelGateway Create();
}

allowing my code to look like:

private IHotelGateway dal = HotelFactory.Create();

...but the C# compiler won't let me, because you can't have static interface members. Sure, I can remove the static requirement from my interface, sure I could use delegates instead, sure I could do a lot of things. But what I don't know is I shouldn't be able to create static interface members...perhaps I can get some smart Microsoft folks to respond?! Stay tuned!

Update: Dug up the original thread from Chris Anderson's weblog.

Posted by Christian at 01:51 PM | |

June 12, 2004

Remedy ASP.NET Configuration Error

Sometimes (way too often) you'll come across an error when developing ASP.NET applications. Here are the symptoms: one minute you're coding/debugging/testing no problem. Next minute, you get the dreaded yellow, white and red unhandled exception screen. The page is entitled Configuration Error and the highlighted line says:

The parser error is Access is denied: '[some assembly]'. Having struggled against this insidious beast time and time again, I am pleased to announce that I stumbled upon a solution in the Infragistics Knowledge Base while Googling for a solution! Seems that the Indexing Service isn't playing nice with the Temporary ASP.NET Assemblies.

Check out the work-arounds here.

Posted by Christian at 10:54 PM | |

June 10, 2004

Technorati is cool

According to Technorati, I'm ranked 106,422 of 2,681,383. Let me analyze what this means to me. It sucks to be in the 75th percentile when you're used to being in the 98th or better. My blog currently has 6 inbound blogs. I'm very flattered that 6 people have taken the time to add me to their blogrolls. In the blogosphere, blogroll links are a vote of confidence and credibility. So, thanks to (in no particular order): , Chris Andersen, , Richard Tallent, and Jeff Julian.

Now, stopping to consider this for a moment it means that 75% of all blogs watched by Technorati have less than 6 inbound permanent links. This seems to confirm that most of us are writing because we like the sound of our own voice the look of our own text.


Now playing: Black Eyed Peas - Let's Get It Started (Spike Mix) (Elephunk)

Posted by Christian at 05:13 PM | |

June 09, 2004

Surrogate Keys - the Query Writer's Friend

BrettK (a.k.a. x002548), a member of the SQL Team, posted an entry entitled Surrogate Keys...the Devil's spawn (OK Not really). As Brett acknowledges, this topic always sparks a heated debate. He listed 6 cons of working with surrogate keys, but only one pro. He also asked what other situations might merit the use of a surrogate key. Here's my take on one:

Surrogate keys can be plenty useful when it's a pain in the neck to have to carry around 5+ fields to do a join on the natural key. For example imagine an entity, Party where you have a single ID (datatype irrelevant) that serves as the PK. You want to model the relationships between two Partys over time. You create an entity PartyRelationship that contains both Party's id's and the start and end dates for the relationship. However, two parties can have several relationships. You may be a Microsoft employee, but also a customer. So let's assume a RelationshipType entity that has a FromPartyRole and ToPartyRole and a Description. To capture all these requirements, your PartyRelationship entity now has FromPartyId, FromPartyRole, ToPartyId, ToPartyRole, StartDate as it's "natural" PK. EndDate is not needed in the PK. With me so far? Next, assume you have entities that relate to PartyRelationship (think of Agreements perhaps) and you can see that you're going to have to carry around these five fields in your join. I would much prefer to have a clustered, unique key on the five fields and have a surrogate key, PartyRelationship Id to simplify my queries. As for where I pulled this hypothetical from...SQL 2000 Enterprise Edition ships with the Silverston Data Model in its samples directory.


[Listening to: Gimme Shelter - Rolling Stones - Forty Licks (Disc 1) (4:32)]

Posted by Christian at 12:17 PM | |

June 04, 2004

Free Xml Editor

An obligatory post for a blog entitled 'xml-blog': get a free copy of Altova's Xml Spy 2004 Home Edition here.

[Listening to: Caballo Viejo - Roberto Torres - (3:57)]
Posted by Christian at 09:04 AM | |

June 03, 2004

Tip for Using App.Config files with NUnit from Visual Studio

At some point you may very well need to call code like the following from your test class library project:

string myValue = ConfigurationSettings.AppSettings["Data.Key"];

Subsequently, when running NUnit you may find that no value is returned from the expression above. This is because NUnit is looking for an xml configuration file with the same name as the assembly + .config in the directory the loaded assembly is running from.
Example: Suppose your assembly is located at C:\Code\My Project\MyAssembly.dll For the ConfigurationSettings.AppSettings call to work properly, you need to have a file at c:\Code\My Project\MyAssembly.dll.config.

Well, an easy way to automate the creation of this file from Visual Studio is to right-click on the project and choose properties from the context menu. Then, under common properties -> build events, add set the following value for the Post-Build Event Command Line:

copy $(ProjectDir)App.config $(TargetPath).config

This will make Visual Studio copy the App.Config file into the appropriate bin\Debug or bin\Release directory (depending on the current configuration) so NUnit will find the file. Happy Unit Testing!

[Listening to: Headstrong - Trapt - Trapt (4:46)]
Posted by Christian at 02:49 PM | |