standalone settings for a c# dll - updated - c#

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!

Related

How to read configuration in a class library located in a different project?

I have my database related stuff in another project which is a class library. I would like to specify the connection string in my config.json file. However, I couldnt find out how to read the configuration. Inside the static constructor of my SessionFactory I call:
var builder = new ConfigurationBuilder()
.AddJsonFile("config.json");
Configuration = builder.Build();
However, I get an exception that the config file is not found since it's being searched in the executed application (which is a separate project). I tried to set the base path but no luck with that as well.
How do I read the config file in class library in a separate project ?
This is the same as when previously using app/web.config. The configuration specific to your currently executing context should be local. If you want access to settings specified for a different project, you should instead add those settings to your current project's configuration.
For example, for the structure;
src
DataProject
config.json
ApplicationProject
config.json
Because you are executing ApplicationProject, all configuration needs to be specified in ApplicationProject\config.json, and then made available later to DataProject via dependency injection or otherwise. DataProject\config.json is irrelevant, because DataProject will not be the executing assembly.
If you have configuration values in DataProject\config.json that are neccessary when executing ApplicationProject, then you should copy those values into ApplicationProject\config.json.

How to use app config of an imported C# project

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!

Shared configuration between an .exe and a .dll

I'm trying to work with a settings.settings file in my project. There are values that need to be shared between the .exe file and various DLLs. I'd rather not just pass these values around, I'd like to access them when I need them but each project sets up its values with slightly different names and therefore aren't reachable by the other projects.
Is there any way to share the contents of the app.config file between an .exe and a .dll using the settings.settings approach? Or do I need to go back to using ConfigurationManager in order to do this?
Just put your settings in the App.config file, and read them from your dll. In fact I believe it's the only place your dll will look for settings/config, local config for the dll is ignored.
Here's a quick example to ensure the dll has no strong references to the application. This code isn't great but you get the idea.
private string GetSettingValue(string key)
{
string executingAssembly = Assembly.GetEntryAssembly().GetName().Name;
string sectionName = "applicationSettings/" + executingAssembly
+ ".Properties.Settings";
ClientSettingsSection section =
(ClientSettingsSection)ConfigurationManager.GetSection(sectionName);
// add null checking etc
SettingElement setting = section.Settings.Get(key);
return setting.Value.ValueXml.InnerText;
}
Alternatively have a common dll with the shared settings and take a dependency from each assembly that needs to share the config. This is far cleaner.

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