Introduction
Generally there could be a requirement such that any
independent component needs to have its own configuration settings. For example, I have a VC++ application which acts as a container so
that it can load an ActiveX control in it. Now as a new technology I want to use
some plugin to be built in Visual C# language using the .NET Framework. As we
already know we can build the Active X component using the .NET Framework. Now let’s
say my component plugin needs to interact with a database so I need to provide it
a connection string and I can’t hard code it inside my component so I decide
to have an application configuration file (i.e., App.Config file), but how can I map
this file to my plugin when it is running in my VC++ container?
This article explains how we can solve this issue, and how
can we map this config file even when it is converted to an ActiveX control and
running in another environment.
Background
Need to have a basic knowledge in creating an ActiveX control
or look for my next article “How to create an ActiveX control using the .NET Framework”.
Explanation
We may have other options like maintaining a separate XML file
and having all the complex custom access through the XML file using XPath
technology. But the way we access this configuration file using the System. Configuration.ConfigurationManager
class is very flexible and comfortable.
The solution is simple,
we need to create a class and name it. I named it “ChangeMyAppConfig”
and this class need to inherit the “AppConfig” class.
public class ChangeAppConfig : AppConfig
{
private readonly string oldConfig =
AppDomain.CurrentDomain.GetData("APP_CONFIG_FILE").ToString();
private bool disposedValue;
public ChangeAppConfig(string path)
{
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", path);
ResetConfigMechanism();
}
public override void Dispose()
{
if (!disposedValue)
{
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", oldConfig);
ResetConfigMechanism();
disposedValue = true;
}
GC.SuppressFinalize(this);
}
private static void ResetConfigMechanism()
{
typeof(ConfigurationManager)
.GetField("s_initState", BindingFlags.NonPublic |
BindingFlags.Static)
.SetValue(null, 0);
typeof(ConfigurationManager)
.GetField("s_configSystem", BindingFlags.NonPublic |
BindingFlags.Static)
.SetValue(null, null);
typeof(ConfigurationManager)
.Assembly.GetTypes()
.Where(x => x.FullName ==
"System.Configuration.ClientConfigPaths")
.First()
.GetField("s_current", BindingFlags.NonPublic |
BindingFlags.Static)
.SetValue(null, null);
}
}
The main AppDomain has
a property called APP_CONFIG_FILE
where it stores the configuration file
information. Now we need to fetch this property using the AppDomain.GetData()
method
and set our new configuration file path using the AppDomain.SetData()
method. It’s not
enough to change the value of the property with this we need to reset the
configuration mechanism as we are doing the same in the ResetConfigMechanism()
method in
the above code.
That’s it. Now you need
to call the ChangeAppConfig()
method from your component by providing a valid
configuration path.
After calling this
method you can access the configuration file settings using the System.Configuration.ConfigurationManager
class as we do normally in every application in .NET.
Example:
public string strCommonFolder = ConfigurationManager.AppSettings["FolderPath"];
Thank you. Hope this will help you....!