5

I am writing a Web API 2.0 project and a test project using Visual Studio 2013.

In the test project, I saved some information in the Settings.settings file (under TestProject->Properties in the Solution Explorer). One of the things saved there is the connection string to a database that is stored locally.

Unfortunately, the connection string will be slightly different on each person's computer when they download the repo. When people push their code to the master repo it overwrites the connection string, affecting everyone else.

What is the best way to make this configurable for each user such that everyone can have their own database path, but pushing to master repo won't affect anyone?

Edit

I don't think this is exactly a duplicate of that other question. Although, yes, my configuration settings are stored in app.config (since they happen to be application settings rather than user settings), following the solution in the other answer will lead me with the same problem. The app.config will contain configSource="otherconfig.config", and when people push that file to the master repo, it will still clobber other people's values. I need something that allows the custom configurations to be source-controlled without affecting the other users of the project.

Community
  • 1
  • 1
  • @George I think your duplicate is not a duplicate. This question is about settings in Visual Studio. The question you link to is about app config files. Not the same thing. – David Heffernan Jan 16 '14 at 16:14
  • 1
    The `otherconfig.config` can't be in source control, each user needs to have their own. – George Stocker Jan 16 '14 at 16:22
  • @George I recognize that, which is why I'm saying it's not the answer to my question. I want something source-controlled so that each user has the ability to revert changes as well as back it up. –  Jan 16 '14 at 16:24
  • @George Like for example, if I set my project into Debug mode and push it to master, nobody else has their project suddenly switch to Debug mode. That's the behaviour I'm looking for, but backed up in the repo. –  Jan 16 '14 at 16:34
  • @ChrisCameron The things you want are diametrically opposed. Why does that separate file need to be in source control? If you want individual control, you can't suddenly want central control. – George Stocker Jan 16 '14 at 16:41
  • If you don't edit your config file often, or at all, you can just unversion it. – Jedediah Jan 16 '14 at 16:44
  • @GeorgeStocker Because the other users would benefit from being able to change their settings and revert to older versions, just like we have the benefit of doing the same now with the plain app.config. Imagine a .config file with sections like , , etc and these are choosable just like Run/Debug configurations. The choice is saved on my computer, but the config is in the repo. –  Jan 16 '14 at 16:44
  • @GeorgeStocker, or similarly the sections might be . –  Jan 16 '14 at 16:45

2 Answers2

4

Visual Studio handles this automatically for WEB projects through Web.config transformations

You'll need to install a separate plugin for use with App.config and non-web projects. http://visualstudiogallery.msdn.microsoft.com/579d3a78-3bdd-497c-bc21-aa6e6abbc859 The plugin basically adds the same functionality to app.config files, and works with the same syntax in the transform files.

Your best approach to this is to use Build Profiles. Have a developer-specific Web.developer.config and with that you get each user to choose their name in Configuration Manager. Then just make the new config, which is technically an XSLT make the changes needed for each team member.

Think of it as Debug vs Release configs, except in your case you'll have many Debug (one for each user). The Build profile you set doesn't get checked into TFS, so you're fine.

This is what a subconfig looks like:

  <?xml version="1.0" encoding="utf-8"?>

  <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <!--
      In the example below, the "SetAttributes" transform will change the value of 
      "connectionString" to use "ReleaseSQLServer" only when the "Match" locator 
      finds an attribute "name" that has a value of "MyDB".
     --> 
      <connectionStrings>
        <add name="RavenDB" connectionString="Url=http://xxx/databases/xxx" xdt:Transform="Replace" xdt:Locator="Match(name)"/>
      </connectionStrings>

    <appSettings>    
      <add key="BaseUrl" value="http://xxx" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
    </appSettings>
    <system.net>
      <defaultProxy enabled="true" />
        <mailSettings>
          <smtp xdt:TrandeliveryMethod="Network" transform="Replace">
            <network xdt:Transform="Replace" host="xxx" defaultCredentials="true" />
          </smtp>
        </mailSettings>
    </system.net>
  </configuration>

More info on web.config transforms http://www.hanselman.com/blog/ManagingMultipleConfigurationFileEnvironmentsWithPreBuildEvents.aspx

Alexandru Puiu
  • 741
  • 6
  • 16
  • Is this applicable to app.config as well? The test project doesn't have web.config because it's not a web project. –  Jan 16 '14 at 17:07
  • Yes, .config files are transformed and used by Visual Studio during the build/runtime process. I can post some examples if you need – Alexandru Puiu Jan 16 '14 at 17:15
  • Hanselman's blog seems to think I need a plugin called SlowCheetah to pull off what you're suggesting http://www.hanselman.com/blog/SlowCheetahWebconfigTransformationSyntaxNowGeneralizedForAnyXMLConfigurationFile.aspx –  Jan 16 '14 at 17:17
  • Visual Studio added this functionality a while ago, no 3rd party plugin is required. I updated my answer with sample code to get you started on them. – Alexandru Puiu Jan 16 '14 at 17:27
  • I made an app.Debug.config, built for Debug, and then ran Tests->Debug->All Tests. I set a breakpoint in a test so that I could check on the value of the ConnectionString property. It stays blank (what I left in app.config) instead of the proper string from app.Debug.config. Is there something else needed to hook up this file? –  Jan 16 '14 at 21:47
  • 1
    It seems you were right about the plugin for app.config. This functionality is supported out of the box on web.config, but it seems to be web-project specific. Try installing the plugin you mentioned http://visualstudiogallery.msdn.microsoft.com/579d3a78-3bdd-497c-bc21-aa6e6abbc859 – Alexandru Puiu Jan 16 '14 at 22:38
  • I just installed it, created a new test console app, added a blank key called "test" to AppSettings, created a new config in Configuration Manager, right-clicked on app.config -> Add Config Transforms, set my new configuration as the running config, added a transform for the "test" key I created, and I was able to read the transformed value. If you have any problems with it let me know, and I'll post more detailed steps. Take a look at this as well for more info on transforms http://www.hanselman.com/blog/ManagingMultipleConfigurationFileEnvironmentsWithPreBuildEvents.aspx – Alexandru Puiu Jan 16 '14 at 22:47
  • Okay, your edit on using SlowCheetah seems to work out. Took me some doing but I finally got the plugin to work and put out different app.config files based on the build configuration. Thanks! –  Jan 20 '14 at 16:04
  • It might be worth reformatting your answer to say you need the plugin at the top though, so that future people don't start writing their own config if they don't read the whole thing :D –  Jan 20 '14 at 16:06
  • Thanks, cleaned it up a bit – Alexandru Puiu Jan 20 '14 at 18:31
0

The way I handle this problem is by adding a folder into my app that has only assets that don't get included in the build/publish. One of the things I include in that folder is DeveloperName.App.config files for each of my developers. Then I leave the the actual App.config file out of source control. When they check out the project, they copy their personalized DeveloperName.App.config file to the project folder and rename it to App.config.

This isn't perfect, but it gives you at least most of the goals you're looking for: The developers each get their own App.config file they can maintain and keep in source control. And the changes they make to App.config don't clobber each other every check-in.

Katie Kilian
  • 6,815
  • 5
  • 41
  • 64
  • Yeah this would basically be my fallback solution, other than maybe figuring out a way with environment variables. –  Jan 16 '14 at 17:18