This morning I was trawling through some of the implementation details of the Client Application Services that are new to the .NET FX v3.5/Visual Studio 2008 and came across a couple of points of interest:
Firstly, one of the advanced settings for the Client Application Services is a connection string that determines the database where credential information will be cached for use when the application is offline. In the dialog it states that you can simply set the connection string to “Data Source = |SQL/CE|” if you want the framework to handle naming and creation of the database. Thinking that someone at Microsoft would have thought about this a bit I assumed that this was a feature of SQL Server Compact Edition (SSCE) that I’d missed. Unfortunately I gave them too much credit and if you look at the implementation of the CreateDBIfRequired method of the System.Web.ClientServices.Providers.SqlHelper class you will see that the string literal “|SQL/CE|” is hard coded, not once but three times (have these guys heard of constants, or resource files?). It gets worse – it’s case sensitive, and yet when they create the SqlCEConnection (don’t scare yourself by looking at that code) they do a case-insensitive check against the name.
The second thing, which actually just made me laugh rather than being bad, was the name of a resource that is used in the above method. When the method attempts to connect it can fail with a TypeLoadException if SSCE is not installed/available on the machine. The code handles this and throws a new ArgumentException (not sure about this being the best exception type to throw either) with a message loaded from a resource file with the name “AtlasWeb.SqlHelper_SqlEverywhereNotInstalled”. Interestingly this is a mix of two code names, “Atlas” and “SqlEverywhere” – I guess it was just going to be too hard to rename this resource!
So, what are the morals of this exercise? Well I guess the obvious one is don’t use string literals in your code (even for one-offs) – it’s not that hard to make them constants or even resources. The other point is that you really need to consider ownership of code/functionality. In the case of the |SQL/CE| literal, this to me would be better off part of the SSCE code base so that it is available for other uses (similar to the |DataDictionary| constant).