Monday, June 28, 2010

When writing .Net Providers do not forget to check for orphan name-value pairs

Today while I was reviewing some code I saw reasonable code (shown below) which I modified to be better code. Why do I say better? Well, a common production bug is mistyped or mis-cased attributes for providers in the configuration file.  These bugs can take a long time to track down – it depends on someone with sharp eyes!  The code modification will immediately identify any orphaned name-value pairs, a typo breaks the initialization and the fix happens in seconds, not hours.

 

The key is to remove all of the name-pair values that you are using (as they are consumed) and then check if there are any orphans after the base processing.  All of the good provider sample codes that I have seen does this. Once I saw the logic, it has becomes a regular code-review item. The pattern is a good one for making deployments more robust – a typo is often hard to track down.

 

Reasonable Code

 

public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{

    ServicePortalId = new Guid(config["ServicePortalId"]);
    CurrentUserSessionKey = config["applicationName"] + "CurrentUser";
    if (config["IdentityServiceId"] != null)
    {
        IdentityServiceId = new Guid(config["IdentityServiceId"]);
    }
    base.Initialize(name, config);
}

Better Code

Another item that was added is fall thru for null values done using ??.

 

public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
    Guid test=Guid.Empty;
    if(config["ServicePortalId"] !=null)
    {
        if(Guid.TryParse(config["ServicePortalId"] ,out test))
        {
        ServicePortalId =test;
        }
        config.Remove("ServicePortalId");
    }
    
    CurrentUserSessionKey = (config["applicationName"] ?? "Unknown") + "CurrentUser";
    if (config["applicationName"] != null)
    {
        config.Remove("applicationName");
    }
    if (config["IdentityServiceId"] != null)
    {
        IdentityServiceId = new Guid(config["IdentityServiceId"]);
        config.Remove("IdentityServiceId");
    }
    base.Initialize(name, config);
    if (config.Count > 0)
    {
        var errors = new StringBuilder("The following configuration values are unknown:");
        foreach (string key in config.Keys)
        {
            errors.AppendLine(key);
        }
        throw new ConfigurationErrorsException(errors.ToString());
    }
}

1 comment: