.NET .config HELL - c#

I have the following projects:
MVC
Console application
Class library
Windows forms application
COM Library
All these applications need to use a single configuration file. As far as I understand, app.config files are for windows, console applications and class libraries when web.config are for the web projects.
The same configuration need to be accessible in all of these projects. I have read that it's suggested to use machine configuration file, but we won't always have access to that, therefore configuration files must reside within our solution.
I don't fully understand how the configuration files get build. Currently I wrote a simple project where I have the following:
Class library to store for serving configuration files. A have attempted to do this through reflection.
Windows application that should read the app.config from a class library.
When I execute the following code I expect to get a configuration file with test values:
_applicationSettings = ConfigurationManager.OpenExeConfiguration(
System.Reflection.Assembly.GetAssembly(typeof(WCSConfiguration)).Location
).AppSettings;
What I get instead is an empty application settings file.
Class library has the following App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="TestTextKey" value="TestTextValue"/>
</appSettings>
</configuration>
I have tried using .GetExecutingAssembly() method which I expect to return an assembly of a code that's currently being executed. This didn't work, instead it has returned the assembly of a Windows application.
GetAssembly(type(WCSConfiguration)) has returned a right assembly, however, the configuration file was missing in the bin/debug directory.
I have a feeling that either I'm doing something fundamentally wrong or Microsoft hasn't made this flexible enough. I have also tried to search MSDN for explanation, but this hasn't been documented well IMO.
I have also left COM in bold because I'm not sure whether any config files would be available to COM library at all. Firstly I would like to get other projects to work.
I understand that this is a lot of information. Any help would be greately appreciated. Previously we have chosen to use registry, but this has turned out to be nasty, mainly because access to registry is not available in some scenarios. Additionally we now have multiple versions of the applications and switching between branches is a half an hour job :(
Thank you
Edit:
If I add the dll's config sections to app.config that means that these settings will be available only from that application. Please correct me if I'm wrong. Example that I have provided is a scaled down version. In total there are about ten windows applications, a single MVC project and range of class libraries all of which need to make a use of that configuration.
Configuration settings are mostly connection strings, lookup values that do not belong in the database and few other minor settings. Main concern at this point are the connection strings. There are few minor releases of the application where each release points to a different database.
What I'd like to get out of this is a good workable solution so that it can be posted online and other people who come across the same problem won't spend days of their time.
Morale of the story IMO:
Use both App.config and Web.config to store location of your own configuration file.
Write simple XML serializer to read/write config and DLL for serving the configuration.
COM objects are a long story and were implemented with a "hack", since neither App.config or Web.config are available in COM DLLs.

Note ConfigurationManager.OpenExeConfiguration needs to be passed the filename of the config file, not the executable.
You'll need to append .config to the path of the executable. To get the exe assembly use Assembly.GetEntryAssembly.
If you have configuration settings you want to share across multiple pieces of code that are not all in the same .NET Process, I would suggest:
Put them in their own myStuff.config.
In .NET code use ConfigurationManager.OpenExeConfiguration to open and access myStuff.config.
Non-.NET code will need to use an XML parser to load and read the settings. Unless you configuration structures are very complex this shouldn't be too hard to encapsulate.
Put the path to myStuff.config in the app.config of each application sharing this configuration for .NET applications. (Not non-.NET applications: depends on what works for that application.)
Another approach, where the configuration structure is the same but the settings are per-application would be a custom configuration section.

A couple of general points -- add the dll's config sections to the app.config file rather than relying on the dll's config file to get picked up; and app.config actually gets renamed to .exe.config on build, so you need to make sure a file of that name's available.
Also -- you're not constrained to using the default config loading mechanism to configure your application. You could create your own configuration classes and just use XML serialization to deserialize and configure at will.

Related

Using app.config correctly

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...

What is App.config in C#.NET? How to use it?

I have done a project in C#.NET where my database file is an Excel workbook. Since the location of the connection string is hard coded in my coding, there is no problem for installing it in my system, but for other systems there is.
Is there a way to prompt the user to set a path once after the setup of the application is completed?
The answers I got was "Use App.Config"... can anyone tell what is this App.config and how to use it in my context here?
At its simplest, the app.config is an XML file with many predefined configuration sections available and support for custom configuration sections. A "configuration section" is a snippet of XML with a schema meant to store some type of information.
Overview (MSDN)
Connection String Configuration (MSDN)
Settings can be configured using built-in configuration sections such as connectionStrings or appSettings. You can add your own custom configuration sections; this is an advanced topic, but very powerful for building strongly-typed configuration files.
Web applications typically have a web.config, while Windows GUI/service applications have an app.config file.
Application-level config files inherit settings from global configuration files like machine.config. Web also applications inherit settings from applicationHost.config.
Reading from the App.Config
Connection strings have a predefined schema that you can use. Note that this small snippet is actually a valid app.config (or web.config) file:
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="MyKey"
connectionString="Data Source=localhost;Initial Catalog=ABC;"
providerName="System.Data.SqlClient"/>
</connectionStrings>
</configuration>
Once you have defined your app.config, you can read it in code using the ConfigurationManager class. Don't be intimidated by the verbose MSDN examples; it's actually quite simple.
string connectionString = ConfigurationManager.ConnectionStrings["MyKey"].ConnectionString;
Writing to the App.Config
Frequently changing the *.config files is usually not a good idea, but it sounds like you only want to perform one-time setup.
See: Change connection string & reload app.config at run time which describes how to update the connectionStrings section of the *.config file at runtime.
Note that ideally you would perform such configuration changes from a simple installer.
Location of the App.Config at Runtime
Q: Suppose I manually change some <value> in app.config, save it and then close it. Now when I go to my bin folder and launch the .exe file from here, why doesn't it reflect the applied changes?
A: When you compile an application, its app.config is copied to the bin directory1 with a name that matches your exe. For example, if your exe was named "test.exe", there should be a ("text.exe.config" in .net framework) or ("text.dll.config" in .net core) in your bin directory. You can change the configuration without a recompile, but you will need to edit the config file that was created at compile time, not the original app.config.
1: Note that web.config files are not moved, but instead stay in the same location at compile and deployment time. One exception to this is when a web.config is transformed.
.NET Core
New configuration options were introduced with .NET Core and continue with the unified .NET (version 5+). The way that *.config files works hasn't fundamentally changed, but developers are free to choose new, more flexible configuration paradigms.
As with .NET Framework configuration .NET Core can get quite complex, but implementation can be as simple as a few lines of configuration with a few lines of c# to read it.
Configuration in ASP.NET Core
Configuration in .NET Core
Simply, App.config is an XML based file format that holds the Application Level Configurations.
Example:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="key" value="test" />
</appSettings>
</configuration>
You can access the configurations by using ConfigurationManager as shown in the piece of code snippet below:
var value = System.Configuration.ConfigurationManager.AppSettings["key"];
// value is now "test"
Note: ConfigurationSettings is obsolete method to retrieve configuration information.
var value = System.Configuration.ConfigurationSettings.AppSettings["key"];
App.Config is an XML file that is used as a configuration file for your application. In other words, you store inside it any setting that you may want to change without having to change code (and recompiling). It is often used to store connection strings.
See this MSDN article on how to do that.
Just to add something I was missing from all the answers - even if it seems to be silly and obvious as soon as you know:
The file has to be named "App.config" or "app.config" and can be located in your project at the same level as e.g. Program.cs.
I do not know if other locations are possible, other names (like application.conf, as suggested in the ODP.net documentation) did not work for me.
PS. I started with Visual Studio Code and created a new project with "dotnet new". No configuration file is created in this case, I am sure there are other cases.
PPS. You may need to add a nuget package to be able to read the config file, in case of .NET CORE it would be "dotnet add package System.Configuration.ConfigurationManager --version 4.5.0"
You can access keys in the App.Config using:
ConfigurationSettings.AppSettings["KeyName"]
Take alook at this Thread
Just adding one more point
Using app.config some how you can control application access, you want apply particular change to entire application use app config file and you can access the settings like below
ConfigurationSettings.AppSettings["Key"]
Application settings enable you to store application information dynamically. Settings allow you to store information on the client computer that shouldn't be included in the application code (for example a connection string), user preferences, and other information you need at runtime.
To add an application configuration file to a C# project:
In Solution Explorer, right-click the project node, and then select Add > New Item.
The Add New Item dialog box appears.
Expand Installed > Visual C# Items.
In the middle pane, select the Application Configuration File template.
Select the Add button.
A file named App.config is added to your project.
take a look at this article

Allowing a Windows Service to be configured

I have a Windows Service that I'm creating and I'm wondering what options are available in order for me let developers configure the service.
The service is part of an over all larger open source project and hence the service is going to be installed on lots of different machines.
Normal I would use a web/app.config for this but I'm not sure if this is possible.
Hence I am looking to so how others handle this case.
you do as you expect. You use the app.config, which will be renamed to <exeName>.configwhen the project is built and then <exeName>.config will be read by the service called <exeName>.
Settings are applied in a layered way and may come from other configuration files on the machine, such as machine.config. You can read about how configuration is handled on MSDN
EDIT
In response to comment: A service will only read the config when it starts (for perf reasons). If you want to reload the config file later, you need to handle that yourself I think.
You could read the last modified date/time of the config file to determine if the file has been changed, or setup a file system watcher and then tell the configuration manager to reload that section again next time it is read, by calling ConfigurationManager.RefreshSection("appSettings") and that section will be reloaded from disk when you next access it. See the ConfigurationManager MSDN docs
You can just use a .config file with the same name as the exe that is the service.
If your service runs as MyService.exe, it's config file would be MyService.exe.config.
In Visual Studio, just add an Application Configuration file. This will add an app.config file to the project.
You can then access things like AppSettings and ConnectionStrings using the ConfigurationManager class, just like you do with ASP.Net applications.

Reference Web.Config file from another project in same solution C#

I have a VC2010 C# Solution, with a number of projects in it.
So for example, I have a web project, and I have a class library.
In the web.config file, I have a key in the <appSettings> section, e.g.
<add key="FileDirectory" value="G:\ftproot\sales" />
I have also added a key in the Web.Production.config file to reflect the file directory on the server.
So when I reference it in my web project (It's MVC) - I do so like this:
var FTPPath = ConfigurationManager.AppSettings["FileDirectory"];
this works fine within my web project. However, I also need to reference this in the class library, which gets to my question - Is there a way to reference a key in the web.config file from another project, e.g. a class library, in the same solution??
All help is appreciated.
Thanks
Yes you can use exactly the same code. .Net will look up the configuration key in the config file of the application which started the app domain. A class library used by such an application will have access to it's config file.
class libraries do not have their own configuration. They use the configuration of which ever executable they are being used in.
This means that for you you should be able to use the same code, and it will read the setting from the config (assuming that it is there).
This is not always convenient though (for example if you write a .net based plugin for a MMC snap-in, as this means you have to modify the mmc.exe.config in the system folder.)
You might be better having a method to pass this required configuration setting into you library code. then in apps where you control the config you can just read it from there and pass it in, and in apps where you can't you can use another approach, like reading from the registry or from a manually read config file. Or have the best of both worlds and make it so you can pass it in, and if this is not done it attempts to read it from the default configuration.
This question has some more details on the pitfalls associated with dll configuration, but also has some techniques for doing it if you need to.

Apply an App.config to my DLL assembly?

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.

Categories

Resources