Perhaps this question has been asked before in a different way, but I haven’t been able to find it.
I have one or more plugin adapter assemblies in my application all having the type IPlugin, for instance. Each adapter has its own settings structures stored in a common directory. Whether they are stored in one contiguous file or in separate ones doesn’t matter. Each adapter can have one or more settings associated with it. The settings will have both a name and the Plugin it will be used for.
How would I create such a configuration system using the following requirements:
- I want to use .NETs built in settings system and avoid writing one from scratch
- The host application will be responsible for locating the plugin settings and passing it to the plugin
- Each plugin will be responsible for reading and writing its own settings to separate concerns. The host application should call Plugin.Save(thePath) and it does its thing.
- All settings are user scoped
So far, I realize that I would need to write my own SettingsProvider, but the provider seems to work in isolation in that there’s no way to pass it parameters such as the path of the plugin directory and the name of the settings. All of the example code I've seen has the provider getting the data from the runtime environment.
The plugins in your example would new up a
PluginSettings
and then call into it like this:Code for PluginSettings:
I had the same issue and blogged about it.
I found an answer albeit a bit convoluted and requires going deep into the architecture of .NET, which isn't well documented. Although ApplicationSettingsBase and IApplicationSettingsProvider are decoupled, there is a bit of recoupling involved to make this work. The solution involves modifying the Settings or your own customized version like so:
Alternatively, you can get around making changes to this class by setting the Context before it's used like so:
In the settings SetPropertyValues of the MySettingsProvider, you can actually grab the data and do something with it:
To use the settings, simply instantiate the class with the parametrized constructor, or alternatively set the Context before using it: