June 22, 2005
.NET | SevenCamels.Framework.Configuration
Version 1.1
I've written a quick update to the SevenCamels.Framework.Configuration library. The first change is to allow regular plugins to be instantiated as needed. The second change is to require all plugins to take their key as their first constructor parameter. The last change is the conversion of all collection classes to typed collections. More details on the three changes can be found below. You can download the latest version of the SevenCamels.Framework.Configuration library, with an updated Example program, here.
Delay Plugin Instantiation
It occurred to me that some applications might not need their plugins instantiated straight away. The instantiation of plugins as they're needed shouldn't be a feature of just the ProviderSectionHandler class alone, so I've made this the default behaviour of the PluginSectionHandler class instead. Since this was the only difference between the PluginSectionHandler class and the ProviderSectionHandler class, there's no need to keep the ProviderSectionHandler class anymore. It's gone.
So, the updated PluginSectionHandler class now behaves exactly the same way as the old ProviderSectionHandler class did. And a new class, the PluginInfoDictionary class, bridges the gap between the new and old behaviour of the PluginSectionHandler class.
To switch from the ProviderSectionHandler class to the PluginSectionHandler class, provider configuration information should change from something like this...
<configSections>
<sectionGroup name="example">
<section name="persistenceProviders" type="SevenCamels.Framework.Configuration.Providers.ProviderSectionHandler, SevenCamels.Framework.Configuration" />
</sectionGroup>
</configSections>
To something like this...
<configSections>
<sectionGroup name="example">
<section name="persistenceProviders" type="SevenCamels.Framework.Configuration.Plugins.PluginSectionHandler, SevenCamels.Framework.Configuration" />
</sectionGroup>
</configSections>
The actual provider configuration section won't need to change. It should continue to look something like this...
<example>
<persistenceProviders default="SqlPersistenceProvider">
<add key="SqlPersistenceProvider" type="Example.PersistenceProviders.SqlPersistenceProvider, Example">
<constructorParameter name="connectionString" type="System.String">blah, blah, blah</constructorParameter>
</add>
<add key="XmlPersistenceProvider" type="Example.PersistenceProviders.XmlPersistenceProvider, Example">
<constructorParameter name="fileName" type="System.String">blah, blah, blah</constructorParameter>
</add>
</persistenceProviders>
</example>
The PluginSectionHandler class now returns the new PluginInfoDictionary class, so provider factory constructor code should change from something like this...
static PersistenceProviderFactory()
{
_providerInfos = (PluginDictionary)ConfigurationSettings.GetConfig("example/persistenceProviders");
}
To something like this...
static PersistenceProviderFactory()
{
_providerInfos = (PluginInfoDictionary)ConfigurationSettings.GetConfig("example/persistenceProviders");
}
The provider factory creation code won't need to change. It should continue to look something like this...
public static IPersistenceProvider Create()
{
// Find the configuration information for the default provider.
PluginInfo providerInfo = _providerInfos.Default;
// Instantiate it and return it.
return (IPersistenceProvider)providerInfo.Instantiate();
}
Plugins aren't automatically instantiated anymore, so plugin code should change from something like this...
PluginDictionary rules = (PluginDictionary)ConfigurationSettings.GetConfig("example/rules");
To something like this...
PluginInfoDictionary ruleInfos = (PluginInfoDictionary)ConfigurationSettings.GetConfig("example/rules");
PluginDictionary rules = ruleInfos.Instantiate();
Note that the PluginSectionHandler class no longer returns a dictionary of instantiated plugins, it just returns the plugin configuration information instead. Getting actual instances requires the extra step of calling the Instantiate method on the PluginInfoDictionary class. Of course, if you don't need to instantiate all the plugins at once, you can call the Instantiate method on the individual PluginInfo objects instead...
PluginInfoDictionary widgetInfos = (PluginInfoDictionary)ConfigurationSettings.GetConfig("example/widgets");
...
Widget defaultWidget = widgetInfos.Default.Instantiate();
...
Widget myWidget = widgetInfos["MyWidget"].Instantiate();
Key the Constructor
The second change to the library was to make each plugin take its key as its first constructor parameter. This is mostly a precaution in case an exception is thrown in the constructor of plugin. By having the key available in the constructor, it can be included in the exception message -- which can be crucial to figuring out which plugin actually went wrong.
Plugin (and provider) constructors should move from something like this...
public Rule()
{
Key = string.Empty;
}
To something like this...
public Rule(string key)
{
Key = key;
}
Not a big change.
Typed Collections
The final change was to make all the collection classes (ConstructorParameterInfoList, PluginDictionary and PluginInfoDictionary) typed. This makes them a bit easier to use -- although they were a pain to write.
Posted by Adam Boddington at 02:47 PM | Comments (0)


Post a comment