Different application settings depending on configuration mode
Asked Answered
F

6

21

Is anyone aware of a way that I can set application (or user) level settings in a .Net application that are conditional on the applications current development mode? IE: Debug/Release

To be more specific, I have a url reference to my webservices held in my application settings. During release mode I would like those settings to point to http://myWebservice.MyURL.com during debug mode I would love those settings to be http://myDebuggableWebService.MyURL.com.

Any ideas?

Forage answered 22/6, 2010 at 4:39 Comment(0)
I
15

I know this was asked years ago, but just in case anyone is looking for a simple and effective solution that I use.

  1. Go to project properties, Settings tab (you'll see your web service URL or any other settings already listed here).

  2. Click the "View Code" button available on the Settings page.

  3. Type this in the constructor.

    this.SettingsLoaded += Settings_SettingsLoaded;
    
  4. Add the following function under the constructor:

    void Settings_SettingsLoaded(object sender, System.Configuration.SettingsLoadedEventArgs e)
    {
        #if(DEBUG)
        this["YOUR_SETTING_NAME"] = VALUE_FOR_DEBUG_CONFIGURATION;
        #else
        this["YOUR_SETTING_NAME"] = VALUE_FOR_RELEASE_CONFIGURATION;
        #endif
    }
    

Now whenever you run your project, it will compile only the line that matches the current build configuration.

Incardination answered 18/9, 2012 at 22:48 Comment(3)
Where/how do you specify the changes per configuration? For e.g., if I create a configuration called "QARelease", how would I check that this is the current one?Expound
Not sure if I understood you correctly, but there is #if(DEBUG) preprocessor directive for distinguishing between DEBUG and RELEASE configurations.Moreover you could define your own compilation symbols per configuration and use them in #if.Incardination
Thanks. I wasn't sure where your DEBUG came from.Expound
H
18

This is somewhat late to the party, but I stumbled upon a nice way of implementing the web.transform approach for app.config files. (i.e. it makes use of the namespace http://schemas.microsoft.com/XML-Document-Transform)

I think it is "nice" because it is a pure xml approach and doesn't require 3rd party software.

  • A parent / default App.config file is descended from, according to your various build configurations.
  • These descendants then only override what they need to.

In my opinion this is much more sophisticated and robust than having to maintain x number of config files which get copied in their entirety, such as in other answers.

A walkthrough has been posted here: http://mitasoft.wordpress.com/2011/09/28/multipleappconfig/


Look, Mom - No explicit post-build events in my IDE!

Heteroousian answered 18/12, 2014 at 12:31 Comment(6)
Worked, thanks! If you are using VS 2017 and the error appears that it can not find the Web*.targets, then check out this answer https://mcmap.net/q/81170/-ms-build-2017-quot-microsoft-webapplication-targets-quot-is-missingLateritious
For VS 2017, v10.0 has to be replaced with v15.0 in <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.targets" />.Colugo
Use Project=”$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.targets” for any Visual Studio version (from the comments in the link).Refreshing
There's now a VS plugin for this: Configuration Transform.Nuzzi
Does this work in .net core ? it does not work for me looks like the debug and release files are never usedVaccaro
Link is dead, which makes the answer obsolete. Please copy the relevant parts instead of just referring to the other site.Pantaloon
I
15

I know this was asked years ago, but just in case anyone is looking for a simple and effective solution that I use.

  1. Go to project properties, Settings tab (you'll see your web service URL or any other settings already listed here).

  2. Click the "View Code" button available on the Settings page.

  3. Type this in the constructor.

    this.SettingsLoaded += Settings_SettingsLoaded;
    
  4. Add the following function under the constructor:

    void Settings_SettingsLoaded(object sender, System.Configuration.SettingsLoadedEventArgs e)
    {
        #if(DEBUG)
        this["YOUR_SETTING_NAME"] = VALUE_FOR_DEBUG_CONFIGURATION;
        #else
        this["YOUR_SETTING_NAME"] = VALUE_FOR_RELEASE_CONFIGURATION;
        #endif
    }
    

Now whenever you run your project, it will compile only the line that matches the current build configuration.

Incardination answered 18/9, 2012 at 22:48 Comment(3)
Where/how do you specify the changes per configuration? For e.g., if I create a configuration called "QARelease", how would I check that this is the current one?Expound
Not sure if I understood you correctly, but there is #if(DEBUG) preprocessor directive for distinguishing between DEBUG and RELEASE configurations.Moreover you could define your own compilation symbols per configuration and use them in #if.Incardination
Thanks. I wasn't sure where your DEBUG came from.Expound
B
7

There is, as far as I know, no built in way of doing this. In our project we maintain 4 different settings files, and switch between them by copying each into the active file in the prebuild step of the build.

copy "$(ProjectDir)properties\settings.settings.$(ConfigurationName).xml" "$(ProjectDir)properties\settings.settings"
copy "$(ProjectDir)properties\settings.designer.$(ConfigurationName).cs" "$(ProjectDir)properties\settings.Designer.cs"

This has worked flawlessly for us for a few years. Simply change the target and the entire config file is switched as well.

Edit: The files are named e.g. settings.settings.Debug.xml, settings.settings.Release.xml etc..

Scott Hanselman has described a slightly 'smarter' approach, the only difference is that we don't have the check to see if the file has changed: http://www.hanselman.com/blog/ManagingMultipleConfigurationFileEnvironmentsWithPreBuildEvents.aspx

Bopp answered 22/6, 2010 at 5:6 Comment(0)
F
4

If you want to keep everything in one configuration file you can introduce a custom configuration section to your app.settings to store properties for debug and release modes.

You can either persist the object in your app that stores dev mode specific settings or override an existing appsetting based on the debug switch.

Here is a brief console app example (DevModeDependencyTest):

App.config :

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <sectionGroup name="DevModeSettings">
      <section name="debug" type="DevModeDependencyTest.DevModeSetting,DevModeDependencyTest" allowLocation="true" allowDefinition="Everywhere" />
      <section name="release" type="DevModeDependencyTest.DevModeSetting,DevModeDependencyTest" allowLocation="true" allowDefinition="Everywhere" />
    </sectionGroup>
  </configSections>
  <DevModeSettings>
    <debug webServiceUrl="http://myDebuggableWebService.MyURL.com" />
    <release webServiceUrl="http://myWebservice.MyURL.com" />
  </DevModeSettings>
  <appSettings>
    <add key="webServiceUrl" value="http://myWebservice.MyURL.com" />
  </appSettings>
</configuration>

The object to store your custom configuration (DevModeSettings.cs):

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

namespace DevModeDependencyTest
{
    public class DevModeSetting : ConfigurationSection
    {
        public override bool IsReadOnly()
        {
            return false;
        }

        [ConfigurationProperty("webServiceUrl", IsRequired = false)]
        public string WebServiceUrl
        {
            get
            {
                return (string)this["webServiceUrl"];
            }
            set
            {
                this["webServiceUrl"] = value;
            }
        }
    }
}

A handler to access your custom configuration settings (DevModeSettingsHandler.cs) :

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

namespace DevModeDependencyTest
{
    public class DevModeSettingsHandler
    {
        public static DevModeSetting GetDevModeSetting()
        {
            return GetDevModeSetting("debug");
        }

        public static DevModeSetting GetDevModeSetting(string devMode)
        {
            string section = "DevModeSettings/" + devMode;

            ConfigurationManager.RefreshSection(section); // This must be done to flush out previous overrides
            DevModeSetting config = (DevModeSetting)ConfigurationManager.GetSection(section);

            if (config != null)
            {
                // Perform validation etc...
            }
            else
            {
                throw new ConfigurationErrorsException("oops!");
            }

            return config;
        }
    }
}

And finally your entry point to the console app (DevModeDependencyTest.cs) :

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

namespace DevModeDependencyTest
{
    class DevModeDependencyTest
    {
        static void Main(string[] args)
        {
            DevModeSetting devMode = new DevModeSetting();

            #if (DEBUG)
                devMode = DevModeSettingsHandler.GetDevModeSetting("debug");
                ConfigurationManager.AppSettings["webServiceUrl"] = devMode.WebServiceUrl;
            #endif

            Console.WriteLine(ConfigurationManager.AppSettings["webServiceUrl"]);
            Console.ReadLine();
        }
    }
}
Foscalina answered 22/6, 2010 at 9:46 Comment(0)
F
3

SlowCheetah adds the functionality you ask for not only for App.config but for any XML file in your project - http://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5

Fortuity answered 28/1, 2013 at 12:26 Comment(2)
Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference.Lugubrious
I think this is probably the best answer -- it seems to allow per-build configuration app.config transforms (much like the build in web.config transforms).Huffy
L
1

I had a similar problem to solve and ended up using the XDT (web.config) transform engine, that was already suggested in the answer from ne1410s that can be found here: https://mcmap.net/q/282230/-different-application-settings-depending-on-configuration-mode

But instead of doing it manually as described in his link I used this plugin: https://visualstudiogallery.msdn.microsoft.com/579d3a78-3bdd-497c-bc21-aa6e6abbc859

The plugin is only helping to setup the configuration, it's not needed to build and the solution can be built on other machines or on a build server without the plugin or any other tools being required.

Literalism answered 10/2, 2016 at 12:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.