When I try and use code that makes use of the Enterprise Library Caching Block I get the following error:
The "cachingConfiguration" section is not available in the supplied configuration source.
The section is in my app.config file for that particular assembly though. If I copy the file into the unit test assembly that makes use of the afore mentioned code everything works. Is there any way that I can force it to use the app config that exists in the referenced library so I don't need to duplicate it in every assembly that makes use of it?
Yes.
Select an app.config file to be your master config file (a good choice would be the one in the project of the main application executable).
Now go to your other project (fx. the unit test project). Right-click and select Add Existing Item. Point to the master app.config file and add using the "As link" option:
Add as link http://blog.codevelop.dk/pics/AddAsLink.png
Now you only need to manage one app.config file, and the other projects will 'reference' this file.
Option 2: If you wan't to control what config file the Enterprise Library uses for caching configuration, use:
var fileSource = new FileConfigurationSource(configFilePath);
var factory = new CacheManagerFactory(fileSource);
ICacheManager manager = factory.CreateDefault();
The dll config file that you see in the IDE (if you are using the designer to add settings etc) is largely for convenience. The runtime won't look for it; it wants the file from yourexename.config. Some components provide the facility to specify a separate config file path - I don't know if this is the case for entlib.
Alternatively if you are spawning your own AppDomains you can specify the config file path. And finally some config sections can be referenced in from other files rather than using the file completely (see configSource here) - but in general (and especially for tests) it is easier to just copy the configuration section into the top-level app's config file (or the unit test's config file in this case).
Related
Now I have seen this question before on SO in a variant ways, but surprisingly not in this form:
I have a solution with multiple web services (projects) that need to talk to each other. After publishing each of these web services might end up on a different machine with a different database. To tell each web service where all other web services are, I want to maintain a single config file during development.
I would like to expect that after publishing the config to be present in each published project. And I would like to expect the config file to be editable after publishing, so I can swiftly migrate a certain web service and then just edit all config files of the other web services.
I don't want to do this in the database, for the config file its self should also hold connection settings to the database(s).
I came across the following ideas/thoughts/questions:
I have a dll project called 'common' that is referenced by other projects. Let's give that one a shared.config and build a class in that project that can be used to read out the shared.config by doing System.Configuration.ConfigurationManager.OpenExeConfiguration("shared.config"). Just need to make sure the shared.config will be published along with the DLL.
I would favor this solution, as it would also let me keep a web.config inside each project having just the project specific settings. And have the shared.config having the shared settings. But I read on SO that this should not be considered lightly and could have some unwanted side-effects, like file-access-issues; though I wonder if this would apply to my case. Also I would like to ask your help here on how to actually realize this as I don't think Visual Studio supports app.config for DLL projects out of the box.
I also thought about creating a shared.config file in the Solution Items. Then linking that file inside each project. And in the Web.config of each projects, add: <appSettings configSource="shared.config" /> pointing to the linked file in that project.
Though I cannot find any reason why not to do this, first implementation failed. It seems (at least during development), c# cannot find the linked shared.config file. I'm guessing linking files is not done instantly nor maintained after creating the linked file, but the file is only copied to the projects WHEN I do a publish. Thus leaving the file missing during development. Is this correct?
The config files are app specific. This mean that you can add a config file to a class library but the file will then by used by the app (windows service, webservice and so on) referencing the library.
Same thing for external configSource, this are app specific as well and need to be included withing the project using it.
So if your solution is composed by 2 projects you then need 2 config files. One for each project.
While for a windows based application(services, winforms) the expected folder for config files is the bin directory, for web based projects this will be the directory is the root folder of the virtual directory.
This said, using a shared config file looks the easier solution (and you don't have to copy the app.config from the class library for each project). Here are the steps :
Create a solution folder.
Add the config file to it.
Add the file as a reference for each project needing it. Right click the project and Add existing item - > Choose the file and Add as link
Ensure the file is always copied by setting the copy option (properties of the file) with Copy Always.
At this point you should have the config file deployed into your project directory everytime you compile the solution.
EDIT:
I'd avoid looking into the bin for config files within a web app, the
convention is that file should be in the root, so I would avoid the
first option.
Linked files end up in the bin after building the project. Try the same steps for importing the file but this time simply add it (not as link) and it will be deployed as content in the root of your site, so it can be always available.
If your hosting in IIS it is possible to have a single web.config file at the root site level but Giorgio is right in that app.config files are app specific. it is possible to use custom build steps to automate the copying of config files across multiple projects so personally I would go with that.
This actually drove me a bit crazy. In the end I fixed it like this:
Created a Shared.config file in the dll project 'common', having the contents look like any ordinary web.config/app.config.
Set the file to be Content and Copy Always, so it would surely be copied out to all projects that reference project common. (Though the config file will indeed end up in the bin folder.
Created the class SharedConfiguration inside the common project. The really tricky part was having to use OpenMappedExeConfiguration() , and getting the path to the executable directory (including bin, and without file:// in front of it).
Now when I want to access a setting from the shared settings, I do SharedConfiguration.instance.AppSettings.Settings["CubilisEntryPointUrl"].Value.
(I cannot use SharedConfiguration.instance.AppSettings["CubilisEntryPointUrl"] directly because of this issue)
.
public static class SharedConfiguration
{
public static readonly Configuration instance = GetConfiguration("Shared.config");
private static Configuration GetConfiguration(string configFileName)
{
ExeConfigurationFileMap exeConfigurationFileMap = new ExeConfigurationFileMap();
Uri uri = new Uri(Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase));
exeConfigurationFileMap.ExeConfigFilename = Path.Combine(uri.LocalPath, configFileName);
return ConfigurationManager.OpenMappedExeConfiguration(exeConfigurationFileMap, ConfigurationUserLevel.None);
}
}
In several C# projects I have been using an app.config file to pass various settings to my program, settings like connectionstrings, power levels etc.
However sometimes I have come in situations where the settings aren't updated as expected and I have concluded that I am not that well informed with the proper use of app.config file.
Example:
Replacing the .exe file with a new version (where settings are different) to the output directory without changing the exe.config, results in the program seeing the hard-coded settings and not the settings of the existing .exe.config
So my Questions are:
What is the exact role of exe.manifest file
Every time I create a new .exe do I have to paste in the output folder anything else except the .exe file?
Whats the difference in obtaining the setting value by: ConfigurationManager.'settingName'... rather than:
Properties.Settings.Default.'settingName'?
What is the role of app.config build action?
Sorry If I am asking too much in a single Question.
The app.config file is a file that gets a special treatment when running the associated application. If you executable is named MyApp.exe the app.config file should be named MyApp.exe.config. The role of the app.config build task is to copy the file named app.config in your project to MyApp.exe.config in the output directory.
.NET provides ways to read the contents of the file (it is in XML format) and various parts of .NET will look for different sections in this XML to provide configuration.
A widely used section is the settings section you refer to as Properties.Settings.Default. This section plays together with Visual Studio that provides an editor for application settings. The settings are accessed in the code by using a generated class. Adding a setting will add a property to this class and this property is initialized from a value in the app.config file.
In the Visual Studio editor you can set a value for the setting and you can think of this as a default value for the setting. However, if you overwrite the value in the app.config file the later will take precedence. This allows you to modify the app.config file after installation and rerun the application with a modified setting.
You can also access application settings the app.config file using other methods, but in my oppinion using the Visual Studio editor and the code generated class is the best way to do that.
I am not sure I fully understand the problem that you experience. If you update MyApp.exe and leave MyApp.exe.config intact you should not see a change in the settings used by the application (unless of course you have renamed or changed some settings).
The manifest file provides information about side-by-side assemblies and can be used to request elevated privileges among other things. This is not related to the app.config file.
There quite a few resources about that.
See http://msdn.microsoft.com/en-us/library/ms229689%28v=vs.90%29.aspx
and the (better) overview: http://msdn.microsoft.com/en-us/library/k4s6c3a0%28v=vs.110%29.aspx
app.config is a very powerful tool. It addresses many issue like versioning, migration, upgrading etc. but this requires some in-depth reading from the links above.
Maybe one thing you could do, if you want to copy only .exe file every time you build your app, is make a settings.ini or settings.txt file, put your parameters in this file (that are not secret of course) and read all your settings from there when you start your app.
You can put all your connection string logic in your login form if you have one...
I am creating one class library project.
Now by default I have one App.Config file so that I am putting all environment specific data in that Config file.
Now based on the Environment (whether Dev / Test / Production), I am planning to have three App.Config files in VS 2010 such as
App.Dev.Config
App.Test.Config
App.Prod.Config
Wondering how would the application know which config file to use.
Anyone implemented this scenario. Any Code samples / Articles would be helpful.
Thanks
The app will use the config file named YourExcecutable.exe.config which is by default the file App.config included in your (executable) project.
Note, that .NET only loads one config file for the whole application. You cannot use multiple configuration files (i.e. one per library project) without coding.
Option: You can use postbuild events and different solution configurations to copy one or another App.Config file to the output folder
Option: You can use the ConfigurationManager Class to load an alternate config file by code.
Loading a different application configuration file at run time can be done using the concept of mapped configuration file. To start with, you need to add reference to System.Configuration.dll in your project.
Set the value of Copy to Output Directory property to Copy if newer (Refer screenshot). This has to be done only for non-default configuration files e.g. App1.config, App2.config, etc. Leave the default configuration file namely App.config as it is . Due to this change, all the non-default application configuration files will be available in the project output directory (\bin\debug) when the project is built. Default value of this property is Do not copy.
Here is the code snippet on how to read configuration data from non-default configuration files:
ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap();
configFileMap.ExeConfigFilename = "App1.config"; // app1.config should be present in root directory from where application exe is kicked off
// Get the mapped configuration file
var config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
//get the relevant section from the config object
AppSettingsSection section = (AppSettingsSection)config.GetSection("appSettings");
//get key value pair
var keyValueConfigElement = section.Settings["appSettingsKey"];
var appSettingsValue = keyValueConfigElement.Value;
If you have multiple application (aka app) configuration files then you can keep a setting in default App.config file with the help of which you can make a decision at run time about which non-default configuration file to load e.g. App1.config
Note: Now look at below code:
ConfigurationManager.AppSettings["DeployEnv"]
This code will still read the data from the default App.config file. This behavior can't be changed. There is no way to prohibit the Loading of default App.config file. You have to use alternate means as discussed in this post to read the data from non-default configuration files
Now there is an even better solution: SlowCheetah - XML Transforms
I'm writing a class library as an abstraction to use for logging in any application, service, etc. that I write. I'm making it decently robust by making it very configurable to suit my needs for most application/service logging scenarios that I come across.
The config is designed to specify things such as:
What logging level to write
Write to one log file for all levels
Write to separate files per level
Logging cutoff (periodic, app event, byte size restricted)
Log file expiration (delete log files after file age)
Write as flat text or XML
Log file name format specification
Whether to prefix filename with date
Parent app's name
etc, etc, etc...
I've read some other stackoverflow questions regarding configs for DLL assemblies and it causing conflict between the app.config for the hosting assembly/app. I believe that my assembly has just cause to provide a config file.
Is this a good scenario for that occasion? Is it perhaps a better idea to bake my own config into my project so that my logger reads from XML files to retrieve config values?
What you could do is
create a custom configuration section (using e.g. the COnfiguration Section Designer tool)
put your assembly's configuration into a separate MyAssembly.config file
reference that assembly config file from your host app's config:
<configuration>
<configSections>
<section name="YourAssembly"
type="YourAssembly.ConfigSection, YourAssembly" />
</configSections>
<YourAssembly configSource="MyAssembly.config" />
</configuration>
That way, you can "externalize" your configuration into a separate config file which you have only once (in your assembly's project), and any project needing it just needs those settings in its own config file.
Sounds like a custom config section would work well in your case. Many libraries, such as the Enterprise Library do exactly this. Check out the MSDN article about creating one.
The .NET config mechanism is not meant to handle configuration files for DLLs. You should configure your application with appropriate settings and pass them on to the class you are instantiating from the DLL.
It is possible to add settings to a DLL project as you'd usually do for applications. All you then need to do is copy the relevant sections and entries into the application's app.config manually and it will work.
It is, however, still true that there's no point copying the DLL's config file. It will not be read.
Another mechanism is to have a seperate configuration file (*.dll.config) for your assembly. The technique is shown here: http://blog.rodhowarth.com/2009/07/how-to-use-appconfig-file-in-dll-plugin.html
The above, imitate the standard app.config technique for assemblies.
In my opinion the dll configuration reading code should only exist in the corresponding dll and in a seperate class - with single responsibility of reading configuration entries from the *.dll.config. This is a nice way of having configuration file for an assembly in a way similar to the configuration file (app.config) an executable can have.
I have a config file in my C# class library called MyLibrary.config, in vs 2008.
I created another project, say a simple console app, add reference by "Browsing" the MyLibrary.dll in the bin directory of the class library project, and when I compile, the MyLibrary.config is not including in the bin directory of the output in the console app.
How can I set it so I can include it when I reference the dll?
Cheers
You can't. Your console application is expecting to find a config file with prefix the same as the name as the console application (MyConsoleApplication.exe -> MyConsoleApplication.exe.config.).
In some situations you can share a config file by using the file attribute on the appSettings element:
<appSettings
file="path">
</appSettings>
Note that path is relative to the executing assembly.
As a side note, DLLs do not even use the config file that you've defined in the project. Again, configuration information is read from the a config file with prefix the same as the executing assembly. Thus, even when MyLibrary.dll tries to yank configuration information out of a config file, it will be reading the config file for the executing assembly, not MyLibrary.dll.config.
For more on how config files work, see MSDN.
The standard way to use a config file is to have it the same as the executable, adding a reference to a dll will not include its config file and as far as I know dll's don't load config files on their own, rather they rely on the executable that reference them.
Beyond not being able to do this, I would also advise against this approach.
Rather than trying to tighly couple your settings to the DLL library, consider more of a "Dependency Injection" type approach - i.e. where you pass in the value dependencies (i.e. settings) to the code you are calling (i.e. the library).
The advantage in this is you are not tied to a single method of storing settings. You can then use a database, different config file formats... even hard-coding. It also makes unit testing easier by removing the external file dependency.
There are different ways to implement this, however one example is to pass the configuration settings into the constructor of the class(s) that uses them.