Can a class library have an App.config file?
No, class libraries can hold setting files, but their values will be defined in the application configuration (web.config, app.config...).
That's because of configuration settings overriding feature.
You'll need to declare the assemblies' configuration sections in the app.config or web.config of your application (WPF, SL, ASP.NET...) and define a value for a particular number of settings defined in the proper assembly settings.
EDIT:
Add a setting file to your project and add a setting with application scope, and your assembly would have something like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="Assembly1.Settings1" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<Assembly1.Settings1>
<setting name="settingA" serializeAs="String">
<value>a value</value>
</setting>
</Assembly1.Settings1>
</applicationSettings>
</configuration>
Now you'd need to go to your application, and you need to copy-paste the section group, and section declarations, and the definition of the values for the settings. That's all.
app.config for a class library
You generally should not add an app.config
file to a class library project; it won't be used without some painful bending and twisting on your part. It doesn't hurt the library project at all - it just won't do anything at all.
Instead, you configure the application which is using your library; so the configuration information required would go there. Each application that might use your library likely will have different requirements, so this actually makes logical sense, too.
Read from App.config in a Class Library project
As stated in my comment, add the App.Config file to the main solution and not in the class library project.
c# configuration for class library
In the end (as per @Stand__Sure and @tigerswithguitars I created a new project within my solution which will be a console App. It will be executed at deployment.
Thanks to Stand__Sure for his link to https://learn.microsoft.com/en-us/dotnet/standard/security/how-to-use-data-protection
The console app does the following:
private static void Run()
{
try
{
// Get unencrypted data from Settings.dat
string[] unencrypted = File.ReadAllLines("C:\\Program Files (x86)\\theAPPSettings\\Settings.dat");
string unencryptedGuid = unencrypted[0]; //its only 1 setting that I'm interested in
// Create a file.
FileStream fStream = new FileStream("C:\\Program Files (x86)\\theAPPSettings\\ProtectedSettings.dat", FileMode.OpenOrCreate);
byte[] toEncrypt = UnicodeEncoding.ASCII.GetBytes(unencryptedGuid);
byte[] entropy = UnicodeEncoding.ASCII.GetBytes("A Shared Phrase between the encryption and decryption");
// Encrypt a copy of the data to the stream.
int bytesWritten = Protection.EncryptDataToStream(toEncrypt, entropy, DataProtectionScope.CurrentUser, fStream);
fStream.Close();
File.Delete("C:\\Program Files (x86)\\theAPPSettings\\Settings.dat");
//Console.ReadKey();
}
catch (Exception e)
{
Console.WriteLine("ERROR: " + e.Message);
}
}
The calling app decrypts it as follows:
FileStream fStream = new FileStream("C:\\Program Files (x86)\\theAPPSettings\\ProtectedSettings.dat", FileMode.Open);
byte[] entropy = UnicodeEncoding.ASCII.GetBytes("A Shared Phrase between the encryption and decryption");
// Read from the stream and decrypt the data.
byte[] decryptData = Protection.DecryptDataFromStream(entropy, DataProtectionScope.CurrentUser, fStream, Length_of_Stream);
fStream.Close();
string temp = UnicodeEncoding.ASCII.GetString(decryptData);
Equivalent to 'app.config' for a library (DLL)
You can have separate configuration file, but you'll have to read it "manually", the ConfigurationManager.AppSettings["key"]
will read only the config of the running assembly.
Assuming you're using Visual Studio as your IDE, you can right click the desired project → Add → New item → Application Configuration File
This will add App.config
to the project folder, put your settings in there under <appSettings>
section. In case you're not using Visual Studio and adding the file manually, make sure to give it such name: DllName.dll.config, otherwise the below code won't work properly.
Now to read from this file have such function:
string GetAppSetting(Configuration config, string key)
{
KeyValueConfigurationElement element = config.AppSettings.Settings[key];
if (element != null)
{
string value = element.Value;
if (!string.IsNullOrEmpty(value))
return value;
}
return string.Empty;
}
And to use it:
Configuration config = null;
string exeConfigPath = this.GetType().Assembly.Location;
try
{
config = ConfigurationManager.OpenExeConfiguration(exeConfigPath);
}
catch (Exception ex)
{
//handle errror here.. means DLL has no sattelite configuration file.
}
if (config != null)
{
string myValue = GetAppSetting(config, "myKey");
...
}
You'll also have to add reference to System.Configuration namespace in order to have the ConfigurationManager class available.
When building the project, in addition to the DLL you'll have DllName.dll.config
file as well, that's the file you have to publish with the DLL itself.
Within the VS project, you should set the .config file "Copy to output directory" setting to "Always Copy".
The above is basic sample code, for those interested in a full scale example, please refer to this other answer.
Need to read values App.config from class library
You would typically only want one config file. If this is a web application, it will be the web.config file. You can read this from a class library by adding a reference to System.Configuration
and using ConfigurationManager.AppSettings.Settings["settingkey"]
to access it.
If you really need to access a separate app.config file, you will need to know the path to it and use something like:
ExeConfigurationFileMap map = new ExeConfigurationFileMap();
map.ExeConfigFilename = pathToAppConfigFile;
System.Configuration.Configuration config = ConfigurationManager
.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
setting = config.AppSetting.Settings["settingkey"];
Using app.config with a class library
One thing you could do is to have a seperate settings file just for your library, then you only have to have a reference to it in your entry apps config file.
See the accepted answer in this question for information on this.
Related Topics
Should I Always Return Ienumerable<T> Instead of Ilist<T>
Method Overloading VS Optional Parameter in C# 4.0
Async/Await Different Thread Id
Possible to Iterate Backwards Through a Foreach
Which Is the Correct C# Infinite Loop, for (;;) or While (True)
Explicitly Cast Generic Type Parameters to Any Interface
How to Deserialize a Unix Timestamp (Μs) to a Datetime from JSON
The Calling Thread Cannot Access This Object Because a Different Thread Owns It.Wpf
Datagrid Get Selected Rows' Column Values
How to Get JSON Response from a 3.5 Asmx Web Service
Getting All Controllers and Actions Names in C#
How to Avoid Response.End() "Thread Was Being Aborted" Exception During the Excel File Download
What Is the Correct Way to Read a Serial Port Using .Net Framework
How to Set Conditional Breakpoints in Visual Studio
Convert from SQLdatareader to JSON
Openxml Sdk Returning a Number for Cellvalue Instead of Cells Text