How to use app config of an imported C# project - c#

I'm using Visual Studio 2010 And C# 4.0. I have a project that exposes an interface to a webservice. It has an app.config that defines the bindings for the webservice. I want to expose this project as a library for other clients to use.
However, when I try to import this library project in a client project (say a console application), I get an error because it couldn't find any configuration file associated with the webservice.
Is there a way to use the app.config inside my library project, so that my clients can use it without having to define a config file of their own?

How about you change the library project a little bit:
Change the app.config in the library project build action to "Embedded Resource".
Change the code when reading config, check if config exist, if not extract the app.config from Embedded Resource to current folder and then use something like ConfigurationManager.OpenMappedExeConfiguration to read it.
After that any project use this library should be able to not worry about those settings.

First create a utility function like below. This function should be in a library or class which could be called from your web service (and of course your main project). Better to add reference to this library in your web service.
public static string GetAppConfigValue(string key)
{
return ConfigurationManager.AppSettings[key] ?? GetAppConfigValue(GetAppConfigFileName(), key);
}
private static string GetAppConfigValue(string appConfigFileName, string key)
{
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = appConfigFileName;
Configuration appConfig = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
return appConfig.AppSettings.Settings[key].Value;
}
Now if you can call GetAppConfigValue(string) from your main project, it returns the value of the cached app.config since it is its own configuration file. You can also call the public function from web service project when it would return the mapped configuration settings. The tricky part here is to properly supply the full path of the config file!

Related

Issue with a DLL reading a ConfigurationSection when called through Service Reference

I have a project (A) referencing a Service (B) via. a Service Reference.
That Service (B) has a reference to a DLL (lets call it Business.dll)
That DLL has it's own accommodating app.config which has some configuration that I would assume would be easily read whether being called internally (as a console app) or externally from Service (B).
Currently, this isn't working. The app.config (or, more specifically, the Business.dll.config file) is not being read at all, and:
(BusinessConfigurationSection)ConfigurationManager.GetSection("GroupName/SectionName");
is always null when called from project (A). Can I not save the Business.dll.config within the bin directory of Service (B), or am I doing something that simply is not possible? Is there a better way that I should be doing this?
Thanks.
You can load a specific config file like this :
Configuration config;
ExeConfigurationFileMap ecfm = new ExeConfigurationFileMap();
ecfm.ExeConfigFilename = <your_config_file_path>;
config = ConfigurationManager.OpenMappedExeConfiguration(ecfm, ConfigurationUserLevel.None);
var mySection = (BusinessConfigurationSection)config.GetSection("GroupName/SectionName");
When you call from Project A, ConfigurationManager will always read from the ProjectA's App.config not from the DLLs
You can use following code to open DLL config,
// Get the configuration file. The file name has
// this format appname.exe.config.
System.Configuration.Configuration config =
ConfigurationManager.OpenExeConfiguration(dllPath); //dll config

standalone settings for a c# dll - updated

I have searched for a while quite fruitlessly for a way to do this.
I am working on a project the has many parts, most of which i can not directly access, but it is extensible. So I have written a dll for it, but the problem is that I need to be able to supply some sort of settings/config that can be updated with out having to recompile the dll.
I don't have access to a main exe's app.config. and the settings/dll.config that vs2010 creates is not being picked up by the dll.
Is this actually possible? a standalone operational config file for a dll?
new update. - I have created a settings.settings file and the all successfully picks up the config data but it seems to bake it into the file when its compiled, when i edit the config after deployment it does not pick up the changes. I tried the first answer below and it didn't work.
thanks
Yes, using the System Configuration namespace you can create a ConfigurationSection which can be used to store any configuration properties you like:
public class MyConfigurationSection : ConfigurationSection
{
[ConfigurationProperty("MyProperty")]
public string MyProperty
{
get { return (string)this["MyProperty"] }
set { this["MyProperty"] = value;
}
}
Then in your assembly project you can read your assembly specific configuration. If your assembly is called MyAssembly, then GetSection() will look for a configuration file called MyAssembly.dll.config:
var myConfig = (MyConfigurationSection)ConfigurationManager.GetSection("sectionName");
Console.WriteLine(myConfig.MyProperty);
I didn't try this specific example, but I have had to do this before. Hope this helps!

How to load executable configuration which is spread across multiple config files?

I have a Windows application called TechReader. Its configuration file is TechReader.exe.config. Some parts of the configuration are kept in other configuration files. So I refer to that config file from the config section created in the exe.config.
<TechReader.ProviderConfiguration file="localProvider.config"/>
Now I want to load the whole configuration of my application using reflection. I use code like this.
Assembly techReaderAssembly = Assembly.GetAssembly(typeof(TechReaderStarter));
ConfigurationManager.OpenExeConfiguration(techReaderAssembly .Location);
TechReaderStarter class is defined in the project whose output is windows application and not the library.
When I use above code, I get TargetInvocationException and ConfigurationErrorsException
Is the approach correct?
Will OpenExeConfiguration load the final configuration generated by merging the exe.config and other referenced config file?
How can I achieve the things?
Note: I want to use this Windows application to install as a Windows Service. I am trying to read the configuration in the ServiceInstaller class (a class which inherits ServiceInstaller) so that the details like service name mentioned in the configuration of the Service will be available to the installutil. For this I have to use reflection to get the exact configuration of the service.

Visual C# app.config file for a referenced assembly

We have a Visual Studio 2010 solution that contains several C# projects in accordance with Jeffery Palermo's Onion Architecture pattern (http://jeffreypalermo.com/blog/the-onion-architecture-part-1/). We have a UI project that is an ASP.Net MVC project, and we have a C# Class Library project called Infrastructure that is referenced by the UI project. In our Infrastructure project we have added an app.config file to contain settings that are specific to the Infrastructure project. At runtime, the app.config file doesn't appear to be available to the Infrastructure project, only the web.config file contained in the UI project. We don't want to put settings that pertain to the Infrastructure project into the web.config file in the UI project, the UI has no need for those settings. How can we make the Infrastructure's app.config file available at runtime? We were thinking maybe we should put a Post Build Copy to copy the app.config out to the UI directory when the application is built - is that the right way to do this, or is there a better way?
Generally, you'll be told that this can't be done. However, you can certainly load a config file using the System.Configuration.ConfigurationManager.OpenExeConfiguration method. You can pass in the file path to your assembly (it doesn't have to be an executable, despite the method name).
Granted, this doesn't merge your assembly's config settings into the executing application's config settings, and I don't think that it should. Your assembly just has to know that it needs to retrieve its settings through a different mechanism than the System.Configuration.ConfigurationManager.GetSection function or the static AppSettings property on that class.
Below is a very simple example for a "Settings" class that loads a .config file for the assembly of which it is a part.
public static class Settings
{
public static System.Configuration.Configuration Configuration { get; private set; }
static Settings()
{
// load a .config file for this assembly
var assembly = typeof(Settings).Assembly;
Configuration = System.Configuration.ConfigurationManager.OpenExeConfiguration(assembly.Location);
if (Configuration == null)
throw new System.Configuration.ConfigurationErrorsException(string.Format("Unable to load application configuration file for the assembly {0} at location {1}.", assembly.FullName, assembly.Location));
}
// This function is only provided to simplify access to appSettings in the config file, similar to the static System.Configuration.ConfigurationManager.AppSettings property
public static string GetAppSettingValue(string key)
{
// attempt to retrieve an appSetting value from this assembly's config file
var setting = Configuration.AppSettings.Settings[key];
if (setting != null)
return setting.Value;
else
return null;
}
}
And the usage...
public class UsageExample
{
void Usage()
{
string mySetting = Settings.GetAppSettingValue("MySetting");
var section = Settings.Configuration.GetSection("MySection");
}
}
Now, you'll still have to work out build issues. Adding an "Application Configuration File" (App.config) item to your class library assembly does cause Visual Studio to copy it to that assembly's output folder as .dll.config, but it is not automatically copied to the output folder of any executable applications that reference that project. Therefore, you'd need to add a post-build step to copy the file to the appropriate location, as you mentioned.
I'd consider having a post-build step on the class library that copies the .config file out to a solution-level "Configurations" folder, then have a post-build step for executable projects to copy everything from the "Configurations" folder to the output folder. I'm not sure if that would actually work well, but if it does then you wouldn't be creating additional dependencies between projects in your post-build steps (that might make maintenance difficult).
EDIT: Ultimately, you should consider whether this is really what you want to be doing. It isn't the normal approach, and generally you might be better served by utilizing the other answer to this question that mentions using the configSource attribute.
Drawbacks to this approach that may not be obvious are that you won't be able to put settings for third-party components into your class library's config file and expect them to be used. For instance, if your class library is using log4net, you can't put log4net's settings in your class library's config file, because the log4net components still expect to load settings from the executable's config file.
Even if you post-build-copy the app.config it will not solve your problem. The application is still a web app, so the config system will use the web.config file. The settings will need to go in there one way or another. One way to still keep those settings a bit separate is to put them into a custom config section, and then put the settings for this section into a separate file. It will still need to be referenced from the web.config though (using a configSource attribute).
Thank you Dr. Wily's Apprentice ! I've added the function for getting the connection string as well:
public static string GetConnectionStringValue(string key)
{
var setting = Configuration.ConnectionStrings.ConnectionStrings[key];
if (setting != null)
return setting.ConnectionString;
else
return null;
}

Wrong App.config being loaded

I have a .NET 3.5 class library I built that reads an App.config file for values it needs. It can pull the config values just fine when I test it in Visual Studio. To test it, I just change the project to a console application and execute a method call.
I have the need to call this class library from many other .NET programs, and I want the class library to be self sufficient (I should be able to call it from any other program, and it should use its own config file, not know about any calling config file etc.).
I can add a reference to the dll (since I am still development I am using VS 2008, haven't thrown anything into the GAC yet) but the App.config that the class library is reading is from the calling program's App.config, not the class library's App.config.
The class library dll has it's config file in the same directory, so it should be able to find it just fine, and the calling application is named differently. I am using the standard key value pairs in the App.config (e.g. name of config file myClassLibrary.dll.config) and getting values out with the following line of code:
String myVal = ConfigurationSettings.AppSettings["myConfigSetting"];
Does anyone know how to fix this?
An app domain in C# can have only one assembly level app.config file. See here on MSDN. An executable will always start up an AppDomain and by default look for a config file with name: EXECUTABLE_NAME.config. For example, SampleApp01.exe will look for SampleApp01.exe.config as its configuration file.
you can place your configs in the machine.config file inside the framework folder by this way you can globally use your configuration in all .Net applications running in that machine,
I believe app.config will always be used by the executable. Just drop it in that directory.
They would do that to ensure the dll can be shared and not have to share the same .config file.
You might be able to create a link from the executable .config file
<appSettings configSource="\lib\app.config">
Or change its name, i don't understand how you can have both app.config files in the same directory..don't they have the same name?
<appSettings configSource="\lib.app.config">
I can't find a way to avoid getting the app.config for the calling dll/exe etc. The only way I have found is to use a hardcoded path and load it that way. Here is code I am using to do that:
using System.Configuration;
...
public static KeyValueConfigurationCollection getAppSettingsFromAppConfig(String appConfigPath) {
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = appConfigPath;
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
AppSettingsSection section = config.AppSettings;
KeyValueConfigurationCollection appsettings = section.Settings;
return appsettings;
}
You then have a collection of KeyValueConfigurationElement, which you can use .Value to get the string from config file with.

Categories

Resources