Simplified Enterprise Library Design-time Configuration Support
A while back I wrote an article on Extending the Enterprise Library Configuration Tool to maintain your Application Configuration. In this article I gave practical guidance in integrating your own configuration in the Enterprise Library Configuration Tool. The FomsDesignManagar class contained a lot of code which could be easily refactored into a base class. The same counts for the ConfigurationNode class. A copy paste version of the DesignManagerBase class.
public abstract class DesignManagerBase : IConfigurationDesignManager
{
public DesignManagerBase()
{
}
#region IConfigurationDesignManager Implementation
public void Register(IServiceProvider serviceProvider)
{
RegisterCommands(serviceProvider);
}
public void Save(IServiceProvider serviceProvider)
{
ConfigurationContext configurationContext = ServiceHelper.GetCurrentConfigurationContext(serviceProvider);
if (configurationContext.IsValidSection(GetSectionName()))
{
ConfigurationNodeBase node = null;
try
{
IUIHierarchy hierarchy = ServiceHelper.GetCurrentHierarchy(serviceProvider);
node = hierarchy.FindNodeByType(GetConfigurationNodeType()) as ConfigurationNodeBase;
if (node == null)
{
return;
}
object settings = node.GetSettings();
configurationContext.WriteConfiguration(GetSectionName(), settings);
}
catch (ConfigurationException e)
{
ServiceHelper.LogError(serviceProvider, node, e);
}
catch (InvalidOperationException e)
{
ServiceHelper.LogError(serviceProvider, node, e);
}
}
}
public void Open(IServiceProvider serviceProvider)
{
ConfigurationContext configurationContext = ServiceHelper.GetCurrentConfigurationContext(serviceProvider);
if (configurationContext.IsValidSection(GetSectionName()))
{
ConfigurationNode node = null;
try
{
object settings = configurationContext.GetConfiguration(GetSectionName());
node = CreateConfigurationNode(settings);
ConfigurationNode rootConfNode = ServiceHelper.GetCurrentRootNode(serviceProvider);
rootConfNode.Nodes.Add(node);
}
catch (ConfigurationException e)
{
ServiceHelper.LogError(serviceProvider, node, e);
}
}
}
public void BuildContext(IServiceProvider serviceProvider, ConfigurationDictionary configurationDictionary)
{
IUIHierarchy hierarchy = ServiceHelper.GetCurrentHierarchy(serviceProvider);
ConfigurationNodeBase node = hierarchy.FindNodeByType(GetConfigurationNodeType()) as ConfigurationNodeBase;
if (node != null)
{
object settings = node.GetSettings();
configurationDictionary[GetSectionName()] = settings;
}
}
#endregion
protected virtual void RegisterCommands(IServiceProvider serviceProvider)
{
IUIHierarchyService hierarchyService = serviceProvider.GetService(typeof (IUIHierarchyService)) as IUIHierarchyService;
IUIHierarchy currentHierarchy = hierarchyService.SelectedHierarchy;
bool containsNode = currentHierarchy.ContainsNodeType(GetConfigurationNodeType());
IMenuContainerService menuService = serviceProvider.GetService(typeof (IMenuContainerService)) as IMenuContainerService;
ConfigurationMenuItem item = new ConfigurationMenuItem(
GetMenuItemText(),
new AddConfigurationSectionCommand(serviceProvider, GetConfigurationNodeType(), GetSectionName()),
ServiceHelper.GetCurrentRootNode(serviceProvider),
Shortcut.None,
GetStatusBarText(),
InsertionPoint.New);
item.Enabled = !containsNode;
menuService.MenuItems.Add(item);
}
protected abstract string GetSectionName();
protected abstract string GetMenuItemText();
protected abstract string GetStatusBarText();
protected abstract ConfigurationNodeBase CreateConfigurationNode(object settings);
protected abstract Type GetConfigurationNodeType();
}
A descendant should then implement the following methods:
protected abstract string GetSectionName();
protected abstract string GetMenuItemText();
protected abstract string GetStatusBarText();
protected abstract ConfigurationNodeBase CreateConfigurationNode(object settings);
protected abstract Type GetConfigurationNodeType();
And the ConfigurationNodeBase class.
public abstract class ConfigurationNodeBase : ConfigurationNode
{
public abstract object GetSettings();
[ReadOnly(true)]
public override string Name
{
get { return base.Name; }
set { base.Name = value; }
}
protected override void OnSited()
{
base.OnSited();
Site.Name = GetComponentName();
}
protected abstract string GetComponentName();
}
Remember the bulky FormsDesignManager in the first article? This is what it looks like when inheriting the DesignManagerBase class.
public class FormsDesignManager : DesignManagerBase
{
private static string MENUITEM_TEXT = "Formulieren Configuration";
private static string STATUSBAR_TEXT = "Formulieren Configuration";
public FormsDesignManager() : base()
{
}
#region DesignManagerBase Implementation
protected override string GetSectionName()
{
return FormsSettings.SectionName;
}
protected override ConfigurationNodeBase CreateConfigurationNode(object settings)
{
return new FormsSettingsNode((FormsSettings) settings);
}
protected override Type GetConfigurationNodeType()
{
return typeof (FormsSettingsNode);
}
protected override string GetMenuItemText()
{
return MENUITEM_TEXT;
}
protected override string GetStatusBarText()
{
return STATUSBAR_TEXT;
}
#endregion
}
Accompanied by the FormsSettingsNode class.
public class FormsSettingsNode : ConfigurationNodeBase
{
private FormsSettings settings;
public FormsSettingsNode() : base()
{
settings = new FormsSettings();
}
public FormsSettingsNode(FormsSettings settings) : base()
{
this.settings = settings;
}
public string FilePath
{
get { return settings.FilePath; }
set { settings.FilePath = value; }
}
public string SecureFilePath
{
get { return settings.SecureFilePath; }
set { settings.SecureFilePath = value; }
}
public FormDataList Forms
{
get { return settings.Forms; }
}
[Browsable(false)]
public virtual FormsSettings FormsSettings
{
get { return settings; }
}
#region ConfigurationNodeBase Implemenation
public override object GetSettings()
{
return settings;
}
protected override string GetComponentName()
{
return "Formulieren Configuration";
}
#endregion
}
These base classes keep the complexity and code duplication out of your design-time custom configuration classes. Comments?