When you need to design your system’s configuration options, one of the available options is to use the Windows Registry. The Registry has several advantages and disadvantages over an xml-based .config file. Let’s go through them:
- Pros
- Windows Standard
- Strongly-typed data
- User Configuration
- Atomicity
- Remote Administration
- Cons
- Difficult to manipulate / Bad tools
- Difficult to backup
- May leave unused data behind
- Can’t easily move settings to a different computer
All of this makes registry-based configuration a good choice for two types of configuration: advanced settings (of the type that no normal user should be touching, but an advanced user may need to change) and user settings (such as last position of a window on the screen, last search parameters, etc).
The focus is to do this:
configuration.WindowsPosition.Top = top;
configuration.WindowsPosition.Left = left;
instead of this:
windowPositionKey = Registry.CurrentUser.OpenSubKey(@"Software\MyCompany\MyProgram\1.0\WindowsPosition", true);
windowPositionKey.SetValue("Top", top);
windowPositionKey.SetValue("Left", left);
When using the registry for configuration, it makes code more explicit and simpler, which is always a plus.
So, how does this work? First, the generated class will look like this:
public class WindowPositionKey
{
private Microsoft.Win32.RegistryKey registry;
public override string KeyName
{
get
{
return @"WindowPosition";
}
}
public WindowPositionKey()
{
registry = Registry.LocalMachine.OpenSubKey@"Software\MyCompany\MySoftware\1.0\Configuration\WindowPosition", true);
}
public int Top
{
get
{
return (int) registry.GetValue(@"Top");
}
set
{
registry.SetValue(@"Top", value);
}
}
public int Left
{
get
{
return (int) registry.GetValue(@"Left");
}
set
{
registry.SetValue(@"Left", value);
}
}
}
It looks pretty simple, and it can even be made manually. And that is generally true for any code generation task. The point here is quantity. When you have several configuration values in different keys, it makes sense to have a tool generate all that code for you. Also, you can do some fancy stuff. For instance, the key named “Configuration” may have several subkeys (let’s say, WindowPosition and ConnectionProxy for this sample). That code will look like this:
public class RootRegistryKey : RegistryGen.RegistryKey
{
private Microsoft.Win32.RegistryKey registry;
public override string KeyName
{
get
{
return @"Configuration";
}
}
public RootRegistryKey()
{
registry = Registry.LocalMachine.OpenSubKey(@"Software\MyCompany\MySoftware\1.0\Configuration", true);
}
public WindowPositionKey WindowPosition
{
get
{
return new WindowPosition(registry);
}
}
public ConnectionProxyKey ConnectionProxy
{
get
{
return new ConnectionProxyKey(registry);
}
}
public override IList<RegistryGen.RegistryKey> GetSubKeys()
{
IList<RegistryGen.RegistryKey> keys = new List<RegistryGen.RegistryKey>();
keys.Add(WindowPosition);
keys.Add(ConnectionProxy);
return keys;
}
}
There are a few changes in WindowPositionKey that must be implemented for this to work. First, we need a constructor with a Microsoft.Win32.RegistryKey parameter. Also, it should inherit from RegistryGen.RegistryKey for the GetSubKeys() method. As you add levels of complexity, manually coding the classes gets more complex.
The code generation task, though, is almost exactly the same. We have a GenerateClass() method that receives all the necessary information to generate a single registry class (className, fullName, etc). For the first change, you only need to change this:
public class <#= CleanName(className) #>Key
to this:
public class <#= CleanName(className) #>Key : <#= Namespace #>.RegistryKey
The second change is as easy. Just change this:
public <#= CleanName(className) #>Key()
{
registry = Registry.<#= GetRootString(registryParts) #>.OpenSubKey(@"<#= fullName #>", true);
}
to this:
internal <#= CleanName(className) #>Key(Microsoft.Win32.RegistryKey registry)
{
this.registry = registry.OpenSubKey(@"<#= lastPart #>", true);
}
and you’re all set!
If you’re interested, you can review the RegistryGen sample in Visual T4 Code Generator alpha for the full sample.

neat info thanks.
ReplyDelete