I'm looking for a best practice for managing configuration on a project with multiple class libraries. I'm looking for maintainability and ease of implementation.
Let's assume a simple example: A console project with 2 class libraries. Each class library need their own configuration settings, and there are some settings that are common to several.
Class Library 1
CL1Setting
GlobalSetting
Class Library 2
CL2Setting
GlobalSetting
A first approach would be to create all the necessary settings on the main project:
GlobalSetting
CL1Setting
CL2Setting
But this present several problems:
It can get cluttered fast if there are lots of settings.
It is not easy to maintain: How to know which settings are needed for each library?
It can create naming conflicts. What if CL1Setting and CL2Setting would have the same name?
An ideal solution for me (although I'm afraid not possible) would be having custom library settings in separate files, or at least different sections. Something like this:
<configuration>
<appSettings>
<add key="globalSetting" value="cl1Global"/>
</appSettings>
<appSettings file="CL1.config" >
<add key="cl1setting" value="cl1setting1"/>
</appSettings>
<appSettings file="CL2.config">
<add key="cl2setting" value="cl2setting2"/>
</appSettings>
</configuration>
Any suggestions?
EDIT
As Ken Henderson suggests, config sections are another approach. However, although with their own advantages, they require coding, so I don't find it ideal though. (This will probably end up being the best option though)
EDIT 2
joseph.ferris suggestion to look at Configuration Section Designer on CodePlex (csd.codeplex.com) was good. I found further problems, reported here (in case some is interested) http://csd.codeplex.com/discussions/278354
I think what you are looking for is a custom configuration section instead of appSettings. This is commonly used by 3rd party libraries (log4net is the first that comes to mind) to provide a way to configure their settings via your app/web config file. Note that this also provides the basis for how MS creates their configuration sections.
I've successfully used this in several different projects including one that included the ability to add new implementations of algorithms to an analysis program.
You could use your own naming convention to reduce the risk of appSettings naming collisions. And/or create custom configuration sections.
<configuration>
<appSettings>
<add key="Shared.Setting1" value="..."/>
<add key="CL1.setting1" value="..."/>
<add key="CL1.setting2" value="..."/>
<add key="CL2.setting1" value="..."/>
<add key="CL2.setting2" value="..."/>
</appSettings>
</configuration>
I'm not sure an administrator would need to know which setting belongs to which library, but a naming convention helps promote a logical grouping - I would use prefixes that are meaningful to an administrator, rather than say a class library name - e.g. "Logging." for appSettings related to logging.
Microsoft uses colon as a delimiter for namespace in some of their code.
Example their Azure samples. Here they use ida: as prefix.
ConfigurationManager.AppSettings["ida:ClientId"];
In Microsoft ASP.NET in the Web.config file you can see:
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
Related
How can I create multiple app.config for different environments where values can be overridden
For example, I want to have app.Debug.config and app.Release.config where I can change specific values in like I do on my web projects (Web.config Transformation Syntax for Web Application Project Deployment):
<add key="Test" value="Value_For_Test_Environment" xdt:Transform="Replace" xdt:Locator="Match(key)" />
For this purpose I used an extension called SlowCheetah. It brings the transformation to non-web projects. In the market you have the tutorial to use it.
https://marketplace.visualstudio.com/items?itemName=vscps.SlowCheetah-XMLTransforms
I'm using .NET MVC
I have about 10 properties I want to store in a configuration file (.config etc.), related to environment/deployment stuff, + other things for quick changes without doing dLL deploys.
I'm using Team foundation service for CI builds etc, and my web.config is obviously under version-contrl.
What I'd like to do is have a settings.config (that's not in version control) file to store these, am I able to do this?
Or does it need to be in web.config?
To answer the title question, yes you can store settings in a separate config file, to do so you need to define the configSource property of appSettings element
E.g.
<appSettings configSource="settings.config" />
and in the settings.config file
<?xml version="1.0" encoding="UTF-8"?>
<appSettings>
<add key="settingKey" value="environmentValue" />
</appSettings>
However, for the sake of environment specific settings, you may want to look at config transforms. Setting up a transform config for each environment then deploying to that environment with the specified build configuration.
E.g. Web.Dev.config (provided you have setup a 'Dev' build configuration)
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<appSettings>
<add key="settingKey"
value="devEnvironmentValue"
xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
</appSettings>
</configuration>
More details of build configuration and config transforms here: http://msdn.microsoft.com/en-us/library/dd465318(v=vs.100).aspx
Or you could take advantage of TFS features and parameterize the environment variables, I don't have a lot of experience with this, but the following should help: http://ig.obsglobal.com/2013/02/tfs-and-continuous-deployment-part-4-parameterized-deployments/
I have a .net github project that is basically a wrapper around a web API. In the test project, I am calling to the API using an API key. I need to keep this key private, how do I accomplish this in a visual studio project?
In some other projects, like python, I can have git ignore the file (config.py) and use something like config.example.py. But in visual studio's case, the project will not compile because of the missing file Config.cs. What is the proper way to solve this? I'm thinking of using this same method of ignoring the file and have them execute a build script that should rename Config.example.cs to Config.cs?
This is the perfect for .config files. Depending on whether its a web or console application, you will have a web.config or app.config file in your project.
You can use the appSettings section to store your API key.
To make things even easier, you can actually have this section read from another file, ie: specialappsettings.config and then just ignore that single file from your repository.
Modify your web.config (or app.config):
<configuration>
<appSettings file="specialappsettings.config">
</appSettings>
<system.web>
<!-- standard web settings go here -->
</system.web>
</configuration>
Create a new specialappsettings.config file:
<appSettings>
<add key="APIKey" value="YourApiKeyValue" />
<add key="AnotherKey" value="AnotherValue" />
</appSettings>
This can be accessed in your code via:
var apiKey = ConfigurationManager.AppSettings["APIKey"];
Notes:
You can keep your settings within the original web.config file as
well but this lets you ignore just the specific settings file from
your git repository without affecting the rest of the project's
necessary configuration details.
The same "key" can be saved in
either file however the external file will override the original
web.config file value.
You are probably looking for the App.config file for a project. It will be copied to <application>.exe.config when you compile it. Users can edit that config file as needed.
In that config file, you can add your API keys:
<configuration>
<appSettings>
<add key="APIKey" value="12345"/>
</appSettings>
</configuration>
Then you can access it from your code using ConfigurationManager.AppSettings:
string apiKey = ConfigurationManager.AppSettings["APIKey"];
One option is to use .config files instead of having secret keys hardcoded in sources.
More info Using Settings in C# and step-by-step guide
<configuration>
<appSettings>
<add key="SecretKey" value="0" />
</appSettings>
</configuration>
var secretKey = ConfigurationManager.AppSettings.Get("SecretKey");
Perhaps you can store the key outside of the Config.cs file and load it at run time.
Bonus, other people using your code won't have to recompile the project to change to their API key.
I added a file app.config to a C# mono project.
Inside the project I used
foreach (string key in ConfigurationManager.AppSettings)
{
string value = ConfigurationManager.AppSettings[key];
Console.WriteLine("Key: {0}, Value: {1}", key, value);
}
The config file looks like this
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="Key1" value="Kevin" />
<add key="Key2" value="150" />
<add key="Key3" value="Rice" />
</appSettings>
</configuration>
No keys are detected. How can I read the config values?
This answer comes awfully late, but for anybody that comes across this, yes, mono does support configuration files. You can use the ConfigurationManager method discussed above or you can even create your own custom settings section in the app.config file and manipulate it through a class which derives from ApplicationSettingsBase. In my opinion, this is a much more natural way of handling the app.config file because you work with a class and strongly typed properties, rather than accessing strings out of an array with the way that ConfigurationManager does it. Creating a class for app settings is pretty easy, too. Here's the MSDN page explaining how to create the class: http://msdn.microsoft.com/en-us/library/system.configuration.applicationsettingsbase.aspx
The only caveat to be aware of with Mono is that the .NET Framework allows UserScopedSettings to be defined in the app.config file (to provide a default value) but Mono will throw exceptions if you do that. The workaround for that is to leave UserScopedSettings out of the app.config file and just define the default value for a property in code. This isn't a perfect workaround because it doesn't give a way to change the default value outside of the code, but this will be sufficient in most cases.
in a small c# project, I'm trying to create a simple custom configsection.
I followed the instructions in CodeProject: Unraveling the Mysteries of .NET 2.0 Configuration and everything work nicely... apart from the fact that I don't get xsd validation and intellisense on the config.
My config is shown below.
<configuration>
<configSections>
<section name="pizza" type="TestConfig.Configuration.PizzaConfigurationSection, TestConfig.Configuration"/>
</configSections>
<pizza name="Margherita" timeToCook="00:10:00" price="15.12">
<cook firstName="Nicola" lastName="Carrer" rank="7" />
<toppings>
<add name="Mozzarella" percentage="0.6" />
<add name="Tomato sauce" percentage="0.28" />
<add name="Oregano" percentage="0.02" />
<add name="Mushrooms" percentage="0.1" />
</toppings>
</pizza>
</configuration>
On this article (XSDExtractor) I found a tool that creates an xsd file for the configsection. It works fine, i.e. it provides intellisense and validation, for the main attributes (e.g. "price") and the single elements ("cook"). However I could not make it work for the collections (the "toppings").
My questions:
Is there any other tool that provides xsd generation of ConfigurationSection classes?
Has someone run XSDExtractor successfully on a ConfigurationSection with a collection property?
Thanks a lot,
Nicola
I haven't used XSDExtractor but one tool which I strongly recommend is Configuration Section Designer. It's a Visual Studio add-in that allows you to graphically design .NET Configuration Sections and automatically generates all the required code and a schema definition (XSD) for them.