Reputation: 2011
I have a VS2013 solution with multiple projects. I have a Web API project, an MVC project, a Windows Service project, and some more business logic projects. Now if a connectionstring changes I have to replace it at least in 3 projects.
I want to have a common configuration solution. What is your suggestion to handle this situation?
I made a Configuration project with an App.config file, but it seems ConfigurationManager use always it's applications config file, for example if I'm using this Config project from ASP.NET, then the web.config is the living config file, and not the Class libary's app.config.
Huh, I found a solution. Perhaps the method to link a configuration file into every projects would be good too.
Finally I made a MyConfiguration project. Which is contains just this one class:
public static class MyConfiguration
{
#if(DEBUG)
public static string ConnectionString = "Data Source=xxxxxxxxx.database.windows.net,1433;Initial Catalog=CRM;persist security info=True;user id=xxxxxxxxxxxxxxx;password=xxxxxxxxxxxxxxx;multipleactiveresultsets=True;
#else
public const string ConnectionString = "Data Source=yyyyyyyyy.database.windows.net,1433;Initial Catalog=CRM;persist security info=True;user id=yyyyyyyyyyyyy;password=yyyyyyyyyy;multipleactiveresultsets=True;"
#endif
}
I just referenced MyConfiguration into my projects, and it will gives me the correct connectionstring for debug and release configurations. What do you think?
Upvotes: 2
Views: 3311
Reputation: 4814
As suggested by lahsrah, you need to use a "Add as Link" for the configuration file. However, there is an extra trick as you don't want to share all of the config between all the projects.
By using the configSource
attribute on a configuration section, it is possible to break up a configuration file into smaller files:
ConnectionString.config
. This would be just the connectionStrings config section.Config
.configSource
attributeConnectionString.config:
<connectionStrings>
<add name="CustomerCorrespondenceContext" connectionString="Data Source=(local); Initial Catalog=MyDatabase; Integrated
Security=True; MultipleActiveResultSets=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
Web.config:
<connectionStrings configSource="Config\ConnectionStrings.config" />
Edit
Based on the comments, it's worth highlighting that this answers the question on how to make the connectionStrings
consistent within the solution. Using the "Add as Link" option makes a copy of the config file when building, so every project is referencing a local copy of the file, not the same file. Therefore, it's not something to help control a deployed environment where changing one file will magically update all apps (that's a different question, with varying options).
So, this is for making the VS Solution manageable for shared configuration between projects of any type.
Upvotes: 2
Reputation: 74177
Use custom config sections and config handlers. See this 3-part series on CodeProject:
Or (even easier), use some variation of Craig Andera's brilliant insight: The Last Configuration Section Handler You'll Ever Need:
This approach is a very generic config section handler. You basically create an XML-serialize class with strongly-type properties and his handler takes care of deserializing the config section into that class. Brilliant!
Once you've done that, your custom config section can be stored externally using the configSource
attribute. In your config file, where you'd normally do something like this:
<config>
<configSections>
<section name="myCustomSettings" type="...my-custom-type-spec..." />
</configSections>
...
<myCustomSettings>
...<!-- some custom xml -->
</myCustomSettings>
...
<config>
You'll do something like this to tell the .Net config system to load that section from the specified external file:
<config>
<configSections>
<section name="myCustomSettings" type="...my-custom-type-spec..." />
</configSections>
...
<myCustomSettings configSource="\foo\bar\baz\myCustomSettings.config.xml" />
...
<config>
The external file is an XML document: the root node has to be the section name just as if it had been cut wholesale from the config file.:
<?xml version="1.0" encoding="UTF-8"?>
<myCustomSettings>
...
</myCustomSettings>
Now, all you have to do is propagate the required standalone config files to where the different applications expect to find them.
It should be noted that the external file located by the configSource
attribute has to be local to that machine: it can't live on the network.
And, put some smarts in your config section handler and it can wire up a file system watcher to monitor that file for changes and reload without restarting the app, though you'll need to add the attribute restartOnExternalChanges="false"
to the <section>
to prevent the app restart first.
Sweet!
Upvotes: 2
Reputation: 9173
Add the file "As a Link" to the second project and you will use the same file for both.
If you need to have project specific settings as well then create a child app.config file and add it as a link to all your projects and make all your project app.config/web.config files inherit from this linked file. Put your common settings in the linked file.
Upvotes: 0