Problem
All of my attempts to add an app.config file to my DLL have failed.
This should not be a problem, according to MusicGenesis’ ‘Putting configuration information in a DLL’. So clearly I’m doing something incorrectly…
My ConnectionString should be returned by the following code from my DLL:
return ConfigurationManager.AppSettings["ConnectionString"];
However, it works great when I copy the app.config file to my console application.
Any ideas?
Asked by MegaByte
Solution #1
Creating a.NET configuration file for a.DLL is not easy, and with good reason. The.NET configuration mechanism includes a number of features to make app upgrades and updates easier, as well as to prevent installed programmes from trampling one other’s configuration files.
There is a significant distinction between how a DLL and an application are used. It’s uncommon that you’ll have numerous copies of an application installed for the same user on the same machine. However, you may have 100 separate programs or libraries that all use the same.NET DLL.
While it’s rare to need to track settings independently for different copies of an app within a single user profile, it’s also unlikely that you’d want all of a DLL’s different uses to share configuration. As a result, when you use the “normal” method to acquire a Configuration object, the object you get back is related to the App Domain’s configuration rather than the specific assembly.
The App Domain is linked to the root assembly, which loads the assembly that contains your code. In most cases, this is the assembly of your main.EXE, which is responsible for loading the.DLL. It is possible to create additional app domains within an application, but you must supply explicit information about the app domain’s root assembly.
As a result of all of this, generating a library-specific config file is a bit of a pain. It’s the same procedure you’d use to generate an arbitrary portable config file that isn’t bound to any specific assembly but makes use of.XML NET’s schema, config section and config element features, and so on. This requires constructing an ExeConfigurationFileMap object, loading data to determine the location of the config file, and then executing ConfigurationManager. OpenMappedExeConfiguration into a new Configuration object with OpenMappedExeConfiguration. The automatic path generating mechanism’s version protection will be disabled as a result of this.
Statistically, you’re most likely utilizing this library in an internal situation, and it’s rare that many apps are using it on the same machine/user. But there is something you should keep in mind if you don’t. You don’t have to worry about access conflicts if you utilize a single global config file for your DLL, regardless of which program references it. If two apps that reference your library are running at the same time, each with their own Configuration object open, when one saves changes, the other app will throw an error the next time you try to access or save data.
The safest and simplest method to avoid this is to require that the assembly loading your DLL also provide some information about itself, or to detect it by looking at the referencing assembly’s App Domain. This can be used to establish a folder structure for storing different user config files for each app that uses your DLL.
If you’re confident you want your DLL to have global settings regardless of where it’s referenced, you’ll need to choose a location for it rather than letting.NET choose one for you. You’ll also need to be ruthless when it comes to controlling who has access to the file. You’ll want to cache as much as possible, only keeping the Configuration instance around for as long as it takes to load or save, opening before and closing after. Finally, a lock mechanism will be required to safeguard the file while it is being changed by one of the apps that utilize the library.
Answered by Chris Ammerman
Solution #2
if you want to read settings from the DLL’s config file but not from the the root applications web.config or app.config use below code to read configuration in the dll.
var appConfig = ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location);
string dllConfigData = appConfig.AppSettings.Settings["dllConfigData"].Value;
Answered by Morbia
Solution #3
I had the same issue and spent several hours searching the internet for a solution, but I couldn’t find one, so I devised my own. I was perplexed as to why the.net configuration system is so rigid.
Background: I’d like my DAL.dll to have its own database and DAL settings config file. For Enterprise Library and its own customizations, I also require the app.config. As a result, I’ll need both the app.config and dll.config files.
What I didn’t want to do was send through all of the app’s properties and settings to my DAL layer!
It is not feasible to bend the “AppDomain.CurrentDomain.SetupInformation.ConfigurationFile” because I require it for typical app.config behavior.
My requirements/opinions were as follows:
I came up with the idea of changing the Settings.cs file and adding a method that opens ClassLibrary1.dll.config and reads the section information into a private field. After that, I overrode “this[string propertyName]” so that the resultant Settings.Desginer.cs calls my new Property rather than the base class. The setting is read from the List there.
Last but not least, there’s the code:
internal sealed partial class Settings
{
private List<ConfigurationElement> list;
/// <summary>
/// Initializes a new instance of the <see cref="Settings"/> class.
/// </summary>
public Settings()
{
this.OpenAndStoreConfiguration();
}
/// <summary>
/// Opens the dll.config file and reads its sections into a private List of ConfigurationElement.
/// </summary>
private void OpenAndStoreConfiguration()
{
string codebase = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
Uri p = new Uri(codebase);
string localPath = p.LocalPath;
string executingFilename = System.IO.Path.GetFileNameWithoutExtension(localPath);
string sectionGroupName = "applicationSettings";
string sectionName = executingFilename + ".Properties.Settings";
string configName = localPath + ".config";
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = configName;
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
// read section of properties
var sectionGroup = config.GetSectionGroup(sectionGroupName);
var settingsSection = (ClientSettingsSection)sectionGroup.Sections[sectionName];
list = settingsSection.Settings.OfType<ConfigurationElement>().ToList();
// read section of Connectionstrings
var sections = config.Sections.OfType<ConfigurationSection>();
var connSection = (from section in sections
where section.GetType() == typeof(ConnectionStringsSection)
select section).FirstOrDefault() as ConnectionStringsSection;
if (connSection != null)
{
list.AddRange(connSection.ConnectionStrings.Cast<ConfigurationElement>());
}
}
/// <summary>
/// Gets or sets the <see cref="System.Object"/> with the specified property name.
/// </summary>
/// <value></value>
public override object this[string propertyName]
{
get
{
var result = (from item in list
where Convert.ToString(item.ElementInformation.Properties["name"].Value) == propertyName
select item).FirstOrDefault();
if (result != null)
{
if (result.ElementInformation.Type == typeof(ConnectionStringSettings))
{
return result.ElementInformation.Properties["connectionString"].Value;
}
else if (result.ElementInformation.Type == typeof(SettingElement))
{
return result.ElementInformation.Properties["value"].Value;
}
}
return null;
}
// ignore
set
{
base[propertyName] = value;
}
}
Simply copy the ClassLibrary1.dll.config file from the ClassLibrary1 output directory to the output directory of your program. Perhaps it will be useful to someone.
Answered by Sven
Solution #4
When using ConfigurationManager, I’m pretty sure it is loading the process/AppDomain configuration file (app.config / web.config). If you want to load a specific config file, you’ll have to specifically ask for that file by name…
You could try:
var config = ConfigurationManager.OpenExeConfiguration("foo.dll");
config.ConnectionStrings. [etc]
Answered by Marc Gravell
Solution #5
ConfigurationManager. AppSettings returns the application settings, not the DLL settings. You can access the DLL settings, but the application settings will be returned.
If you’re utilizing a dll from another program, the ConnectionString should be in the program’s app.settings.
Answered by Jorge Córdoba
Post is based on https://stackoverflow.com/questions/594298/c-sharp-dll-config-file