I don't know the answer to your second question, but is the way I have initialized settings values from a database query. I think this will match the lifecycle the runtime normally expects.
First, create a matching partial class implementation for your auto-generated settings class:
[SettingsProvider(typeof(CustomSettingsProvider))]
internal sealed partial class Settings : ApplicationSettingsBase
{
public Settings()
{
CustomSettingsProvider.UpdateCustomSettings += delegate(object sender, EventArgs e)
{
this.Reload();
};
}
}
The SettingsProvider attribute identifies the class that is the source of your settings.
The event handler is optional. It is a way you can force the settings to get reloaded at runtime, if the values change asynchronously.
Here is what the SettingsProvider looks like:
public partial class CustomSettingsProvider : System.Configuration.SettingsProvider, System.Configuration.IApplicationSettingsProvider
{
// raise this event to cause the settings to be reloaded at runtime after initialization
public static event EventHandler UpdateCustomSettings;
public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection)
{
SettingsPropertyValueCollection result = new SettingsPropertyValueCollection();
// the collection identifies properties to initialize
foreach (SettingsProperty property in collection)
{
SettingsPropertyValue spv = new SettingsPropertyValue(property);
// determine value...
spv.PropertyValue = value;
result.Add(spv);
}
return result;
}
}
There are a few overridable methods in the base class, but most of the work in done in the GetPropertyValues method. The collection argument identifies the properties that need initialization, for each one look up the value, or provide some default value to avoid your NullReferenceExceptions.
We are using this technique for authorization settings. We have several modules in the application, each with a different set of authorization settings, but all are tied to the same CustomSettingsProvider.
The database code to read the settings is separate from the CustomSettingsProvider class, but accessible to the CustomSettingsProvider.GetPropertyValues method through a singleton interface. We added a public static method on the CustomSettingsProvider to raise the UpdateCustomSettings event (since the event and method are static, there is no event "sender", but the event arguments are not used anyway).
When the database query completes and the settings are read in, the static method is called on the CustomSettingsProvider class, which raises the UpdateCustomSettings event and in turn the Settings class invokes it's Reload method. The default Reload implmentation calls the GetPropertyValues method to re-initializes all the setting values with the new data from the database.