问题
I have a C# Project called Application
which is basically considered to represent the top most application layer. All other Layers are treated as ClassLibraries like BUSINESS
, DAO
and UTIL
. Now I want that the application be configurable by using the App.config file. For that purpose I need to make this configuration file visible for the referenced ClassLibraries (Assemblies).
For me, the most suitable solution would be that the UTIL
assembly has access to the App.config and is able to share those accessible items to the upper application layers.
So far I tried to create a Settings.settings file in the UTIL
assembly which defines one item: Name: ElemName; Type: String; Scope: Application
. The App.config file which is located within the Application
assembly contains the following source:
<applicationSettings>
<UTIL.Settings>
<setting name="ElemName" serializesAs="String">
<value>SomeValue</value>
</setting>
</UTIL.Settings>
</applicationSettings>
If I now try to access this property via: Settings.Default.ElemName
,
the build fails with error: 'UTIL.Settings' is inaccessible due to its protection level
A further approach, to make this property visible via a helper class inside assembly UTIL
public String GetElemName()
{
return Settings.Default.ElemName;
}
fails with an: 'System.Configuration.ConfigurationErrorsException' occurred in System.Configuration.dll ... Additional information: Configuration system failed to initialize
How can I get it running? (I only need to read the configuration)
回答1:
The easiest is the following:
Add the required settings in the project properties of the DLL assemblies like you would do for any normal application.
Now, a DLL doesn't actually read its own app.config
. The trick is to copy the entire <applicationSettings>
block from the DLLs app.config
to the application's app.config
and also add the respective line in the <sectionGroup>
section at the top of the file.
Example: Let's assume the app.config
for your DLL looks 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="DLLSample.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<connectionStrings>
<add name="DLLSample.Properties.Settings.MyConnectionString" connectionString="Data Source=..." providerName="System.Data.SqlClient" />
</connectionStrings>
<applicationSettings>
<DLLSample.Properties.Settings>
<setting name="AllowStart" serializeAs="String">
<value>True</value>
</setting>
</DLLSample.Properties.Settings>
</applicationSettings>
</configuration>
And the app.config
of your application looks like this:
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="App.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<App.Properties.Settings>
<setting name="LogPath" serializeAs="String">
<value>C:\Temp</value>
</setting>
</App.Properties.Settings>
</applicationSettings>
</configuration>
After the above described changes, the application's config file should look like:
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="App.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="DLLSample.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<connectionStrings>
<add name="DLLSample.Properties.Settings.MyConnectionString" connectionString="Data Source=..." providerName="System.Data.SqlClient" />
</connectionStrings>
<applicationSettings>
<App.Properties.Settings>
<setting name="LogPath" serializeAs="String">
<value>C:\Temp</value>
</setting>
</App.Properties.Settings>
<DLLSample.Properties.Settings>
<setting name="AllowStart" serializeAs="String">
<value>True</value>
</setting>
</DLLSample.Properties.Settings>
</applicationSettings>
</configuration>
From both your application and DLL code you'll be able to use the normal configuration settings mechanism, like access a value through Properties.Settings.Default.AllowStart
from the DLL's code or Properties.Settings.Default.LogPath
from the application's code.
Two things you can not do:
- Access the DLL config values from your application and vice versa
- Manage the DLLs config values from the application's property page. You need to edit the
app.config
manually to add/remove/modify settings.
Connection strings, by the way, can also be managed that way. I've added to the examples above.
回答2:
I solved this issue in a different way.
The Project called Application
still contains the App.config file. All referenced assemblies (Business
, DAO
, UTIL
, and TestAssemblies) just share the applications configuration.
How to share configuration:
- Project (
Business
,DAO
,UTIL
, etc.) -> Add -> Existing Item -> 'Select' App.config -> Add As Link - Project -> Add Reference -> .NET -> System.Configuration -> OK
string configValue = ConfigurationManager.AppSettings["token"];
How the App.config file looks like:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
...
<appSettings>
<add key="token" value="ConfigValue" />
</appSettings>
...
</configuration>
Without this reference to the existing App.conifg file AppSettings["token"]
won't resolve the value while running with NUnit. If the application is started in debug mode, everything works fine, even without the link to App.config as mentioned by user Maarten
来源:https://stackoverflow.com/questions/19838922/how-do-i-make-app-config-values-visible-for-referenced-classlibraires-assebmlie