Using one app.config file for multiple projects - c#

I have a solution with the following setup:
X amount of class library projects
Y amount of console application projects
Each of these projects may have 0 or more configuration parameters.
Now, I'd like to have only one App.config for user to specify settings and that App.config will only contain parameters of all the reference projects of the console application project to be run.
I've tried giving each project a Settings file and then linking them to the console applications according to their dependencies but that didn't work.
I've also tried just lumping all the configurations together in one class library project and have each console application link to that app.config (or settings file). But that also didn't work (i.e. changes of the app.config or the settings file in the class library will not update the .config of the executable)
Is what I am trying to do possible?

Yes, it is possible. You just need to open the app file. Follow the next example:
ConfigurationManager.OpenExeConfiguration("C:\Test\SomeProject.dll");
XmlNode loggingConfigNode = ConfigurationManager.GetSection("log4net") as XmlNode;
I guess that you will have to open each setting file in order to use the settings, or you will have to consolidate all the settings in a single app.config and then your applications can access the file by open it.

Related

ASP.NET Core 2.2 How to share web.config/launchSettings.json files among projects

I have this solution structure:
AppOne.Account
AppOne.Admin
AppOne.System
AppOne.Data
AppOne.ClassLibrary
AppOne.Account, AppOne.Admin and AppOne.System are ASP.NET Core Application Projects. The rest are libraries.
Currently I have to manually copy and paste the same web.config file to each of them when I deploy and even in development, I have to copy and paste the launchSettings.json file as it contains their environment variables that I need.
Is it possible to store the web.config or launchSettings.json file in a folder and then reference it in my Startup.cs.
I am thinking of storing it in a Solution folder and then reading the in. However, I am unsure if that is possible and I am also unsure of where to read it from.
You don't "reference" the web.config. You put the app/web.config file in the project (or a short cut to the single Config file that actually lives in another folder).
Then in code you use ConfigurationManager.AppSetting... and that will look for the config file in the running project. It's context based.
If you are running the main project it'll look at the main project for the config, if you're running a Unit Test project then it'll expect a config file (or a shortcut) lives in the root of the unit testing project.
A nifty solution is adding config file shortcuts in other projects so you only update one file:

Config file for publishing web service

I have a Visual Studio web service application with the following solution structure (using VS2013 Community):
- [Solution] S
- [Project] S_Service
- S.amsx
- [Project] S_Lib
- File1.cs
- File2.cs
- app.config
The S_Service project is a simple web service project, with just a single asmx file with one WebService method. The project contains a reference to the S_Lib project, a class library to do all the work in terms of the business logic (the request processing).
In S_Lib I have an app.config file in which I store things like directories and file names for stuff which is used by the various components in S_Lib. When I am developing, changes to that file are picked up by the code ok.
Here's the problem: When I publish the S_Service project, the publish directory doesn't contain my app.config - only S_Service.dll and S_Lib.dll. After reading some other posts on StackOverflow (can't seem to find them now), I tried setting the build action on app.config to Content and to Copy Always. Great, this gets the file across to the publish directory, so it looks ok. But, once I deploy the whole lot onto IIS, any changes to the app.config file do not get reflected when the service is run. In fact I can delete the file completely from the IIS directory and it runs just fine. It's as though S_Lib.dll contains a compiled version of the configuration settings. This is no use, as I want to modify the config depending on the machine it's deployed on.
What do I need to do so that app.config is actually used at runtime and that changes are read on the fly?
Just as you wrote, S_Lib.dll contains compiles settings from the time when you set them in VS settings designer. Therefore it is still working (more or less).
You have a web service so you need a web.config. Add one to S_Service project. Then merge app.config content to web.config. Every time you change some setting in S_Lib project you will have to merge changes to web.config as well.
Or you could add app.config to S_Service project as a link by name web.config (not sure if it is possible to create a link with different name). Then when you change settings in S_Lib project they will be referenced in S_Service project automatically.
After failing to find a simple Visual Studio-based solution to do what I want, I implemented a more customised solution. In the library project, I replaced the config lookup method:
internal static string GetConfig(string key) {
return ConfigurationManager.AppSettings[key] as string;
}
with a new method that reads my own settings file (custom format), stored in the solution. It's not perfectly ideal as it means that each project in the solution has to have its own settings file, but it's simpler overall. If anyone is interested please leave a comment and I will elaborate on this solution.

Common app.config for multiple applications

I have several C# console applications, which need to have the same set of settings. I want to avoid duplicity and avoid separate app.config for each application.
Is there any way to read a common app.config file (say common.config) for applications (app1.exe, app2.exe).
Create one file called app.config. Put it in some place outside of your projects' directories, like up in the solution directory. Add it to your projects as a linked item with a relative path to the file. Set the right build action for this item (application configuration) in each project.
Now when each project builds, the file will be copied to the project's output dir with the right name.
You can load an external app.config using the code below:
config = ConfigurationManager.OpenExeConfiguration(Path.Combine("C:\test\root", "Master.exe"));
string logpath = config.AppSettings.Settings["Log.Path"].Value;
And save settings as so:
config = ConfigurationManager.OpenExeConfiguration(Path.Combine("C:\test\root", "Master.exe"));
config.AppSettings.Settings["Log.Path"].Value = "C:\newpath";
config.Save();
You might have to have a master config within one of the applications and point the rest to this. Typically this method is considered bad practice though. There might be issues with different applications locking the file.
#Ran's answer is an option, but each application will still have its own config file after you build. At compile time they will be the same, but at deploy time they are copies.
You can also open one application's config file from another application using:
ConfigurationManager.OpenExeConfiguration(string)
You can have an external config file that all applications reference using:
ConfigurationManager.OpenMappedExeConfiguration
And there's the option to using the Machine config file using:
ConfigurationManager.OpenMachineConfiguration()

.NET Modifying Class Library Application Settings from Host Application

Let's say I have the following scenario in .NET 4.0:
- Solution containing: a) a Class Library b) a Console Application
The Console Application references the Class Library.
What I want is to setup some Application Settings in my Class Library and make it so that these are accessible by the Class Library (host Console Application should not make use of these directly), but also modifiable via a .config file after deployment (so if the user decides they want to change the value of one of the settings, they can do so without having to re-deploy the application.
Is this possible?
As far as I know, the class library will have access to the host files config file via dot net configuration management framework. You can also have a second configuration file with a name known to your library and load it manually at library initialization using the swme framework.
Please Reference System.Configuration
var configurationFileMap = new ConfigurationFileMap(#"c:\myconfig.config");
var configuration = ConfigurationManager.OpenMappedMachineConfiguration(configurationFileMap);
Both the host and the lib should be able to access the myfile.config as long as they know the name of it. If you want to make it more general, you can store the name of the config file under a known registry key
Figured this out after quite a bit of Google-fu.
The final solution I adopted was the following:
I created Settings (which generated an app.config file) in my Service application. I then created links to these settings in both my Code Library project and Console Application project (this is done by going to Add > Existing Item > then hitting the drop-down arrow next to the Add button and selecting "Add as Link". Although the one in the Code Library project is not necessary.
What this does is make it so that I only have 1 settings configuration while in development, while it will still generate a config file for my console application which I can access from both the console application and the Code Library during the development process.
Finally, I used the code below to open the configuration file and access the values. As a disclaimer, there may be an easier way of doing this, but I tried about a 100 combinations and nothing else worked:
String cfgFileName = "IntercompanyConsoleApp.exe.config";
ExeConfigurationFileMap cfgMap = new ExeConfigurationFileMap();
cfgMap.ExeConfigFilename = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\" + cfgFileName;
Configuration cfg = ConfigurationManager.OpenMappedExeConfiguration(cfgMap, ConfigurationUserLevel.None);
// IntercompanyService is the name of my service app, which is where the real app.config file resides -- hence the entries in the xml are based on this application.
// Also, the scope of my settings entries is Application
ClientSettingsSection section = (ClientSettingsSection)cfg.GetSection("applicationSettings/IntercompanyService.Properties.Settings");
Console.WriteLine(section.Settings.Get("Server").Value.ValueXml.InnerText);
Console.WriteLine(section.Settings.Get("Database").Value.ValueXml.InnerText);
This is an obscure issue, but hopefully this saves someone some time in the future because I spent about 4 hours trying to figure this out.

How to handle two or more app configs?

Lets imagine I have three projects in my solution. The first one is executeble and the other two are class libraries.
Every project has it's own app.config file which contain some httpBinding data, some user settings and connection strings.
Then I build the solution and all I get (in the EXE's bin directory) is the only app.config file with the XML elements wich are related to the executable project.
So, the question. How do I suppose to use that another two configs (which are successefully built to their corresponding project bin folders?
You need to put the settings in the dll libraries in the setting file of executable. Or you can make a separate libraries for handling settings of all the projects in the solution. The default setting files look in to app.config.

Categories