We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you two Citrix podcasts. Learn about 2020 trends and get answers to your biggest Citrix questions!Listen Now

x

Application Configuration for different environments

PantoffelSlippers
on
Medium Priority
1,496 Views
Last Modified: 2013-11-07
Hi Experts,

I write a lot of VB.Net desktop applications and I make use of the configuration file a lot.  The problem is that the application would go through so many environments like DEV, TEST, UAT and ultimately production.  Many times more than production environment (different sites or domains).

It is very tedious chaning all the connections strings, UNC paths and credentials stored in the config file when changing between environments.  I've been able to work around this by creating a seperate setting for each environment and name it sloghtly different like ConStr_Dev, ConStr_Test, ConStr_Prod and then have another setting called environment which would contain _Dev, _Test or _Prod.  Changing this one setting would then allow the code to dynamically adjust.

It's not the cleanest way and I was hoping the new .Net 3.5 would provide a built-in feature to cater for this.  Something like different configuration groups that would all have the same settings/structure but different values...

Please advice me

Thanks
Comment
Watch Question

Senior .Net Consultant
CERTIFIED EXPERT
Top Expert 2016
Commented:
That will be the topic of my next article in March (www.emoreau.com). Since .Net 2.0, you already have this feature. Here is something to start you with.

You app.config file needs to look like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
      <connectionStrings>
            <clear/>
            <add name="Dev"
                   providerName="System.Data.SqlClient"
                   connectionString="Data Source=moer-i1520\sql1008; Initial Catalog=DevDB; Integrated Security=SSPI"
      />
            <add name="QA"
                   providerName="System.Data.SqlClient"
                   connectionString="Data Source=moer-i1520\sql1008; Initial Catalog=QADB; Integrated Security=SSPI"
      />
            <add name="Prod"
                   providerName="System.Data.SqlClient"
                   connectionString="Data Source=moer-i1520\sql1008; Initial Catalog=ProdDB; Integrated Security=SSPI"
      />
      </connectionStrings>
</configuration>


Before being able to use the special wrapper provided by the .Net Framework, you need to add a reference to the System.Configuration component.

Now that we have this reference, we will be able to use the ConnectionStringSettingsCollection class that will do the entire job for us. See this method:
Imports System.Configuration

Private Sub GetAllConnectionStrings()
    'Clear the listbox
    Me.ListBox1.Items.Clear()

    'Declare a collection that will contains all the connection strings
    'retrieved from the app.config file
    Dim collCS As ConnectionStringSettingsCollection
    Try
        collCS = ConfigurationManager.ConnectionStrings
    Catch ex As Exception
        'the section is surely not found!
        collCS = Nothing
    End Try

    'If the collection is not empty
    If collCS IsNot Nothing Then
        'Loop through all settings
        For Each cs As ConnectionStringSettings In collCS
            'Add the name of the connection string to the listbox
            Me.ListBox1.Items.Add(cs.Name)
        Next
    End If

    collCS = Nothing
End Sub

Then you can display info of the selected items using:

'The name will become the key
Dim strCSName As String = Me.ListBox1.SelectedItem.ToString
Dim strCS As String
Dim strProvider As String
'extract data from the app.config file
With ConfigurationManager.ConnectionStrings(strCSName)
    strCS = .ConnectionString()
    strProvider = .ProviderName
End With

'Display the required information
MessageBox.Show("You have selected this connection string:" + Environment.NewLine + _
                "     Name     = " + strCSName + Environment.NewLine + _
                "     Provider = " + strProvider + Environment.NewLine + _
                "     Connection string = " + strCS, _
                "Your connection string", _
                MessageBoxButtons.OK, _
                MessageBoxIcon.Information)

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts
PantoffelSlippersOperations Manager

Author

Commented:
Thanks Eric,

I've read several of your articles - they're always excellent!

I'll watch out for it in March.

In the meantime, what you've given me will get me started I'm sure.  

Two immediate questions though:
- Can I creat additional custom sections similar to connections strings.  For example:  DomainCredentials
- Do I need to edit the XML directly or is it still possible through the settings window in VS?

Many thanks
Éric MoreauSenior .Net Consultant
CERTIFIED EXPERT
Top Expert 2016

Commented:
>>- Can I creat additional custom sections similar to connections strings.  For example:  DomainCredentials

Yes but you will need to handle everything manually as .Net won't recognize them.

>>- Do I need to edit the XML directly or is it still possible through the settings window in VS?

You can use VS to edit the App.Config file.
Top Expert 2009
Commented:
How about continuous integration using nant?

We have, kind of, automated the whole build process. We have an xml file containing all the configuration information. There are four sections in the xml file - local, dev, staging and prod. Depending on where we need the deployment to occur, we just delete the other three. When nant runs, it reads the build file. The build file in turn reads the xml config file and sets the appropriate values to, say, connection strings, deploy folders of any other configurable section.

PantoffelSlippers, we used the following article as our bible to set this up. I'll tell you right away that setting this up is not the easiest of things you'll do, but once set up, your deployment is just a 'double-click' away from making things happen.

http://blog.jpboodhoo.com/NAntStarterSeries.aspx
http://blog.jpboodhoo.com/AutomatingYourBuildsWithNAntPart8Videos.aspx
PantoffelSlippersOperations Manager

Author

Commented:
Thanks eric,

Sorry, but what do you mean with:
>>>>Yes but you will need to handle everything manually as .Net won't recognize them.

Thanks again

Cheers
PantoffelSlippersOperations Manager

Author

Commented:
Thanks nmarun,

I'll have a look and post back
Éric MoreauSenior .Net Consultant
CERTIFIED EXPERT
Top Expert 2016
Commented:
You will need to inherit the ConfigurationSection class. See http://msdn.microsoft.com/en-us/library/system.configuration.configurationsection.aspx
PantoffelSlippersOperations Manager

Author

Commented:
Eric,

Does this apply to desktop applications as well?
Éric MoreauSenior .Net Consultant
CERTIFIED EXPERT
Top Expert 2016

Commented:
yes and it is exactly the same code.
PantoffelSlippersOperations Manager

Author

Commented:
Yes OK it looks as if ConfigurationSections might be my answer - I'm just strangely having difficulty making it work!
PantoffelSlippersOperations Manager

Author

Commented:
Eric,

Has your article mentioned earlier in this stream been posted yet?

I had a look on your site - couldn't find it.....

Thanks!
Éric MoreauSenior .Net Consultant
CERTIFIED EXPERT
Top Expert 2016

Commented:
Finally no. This article was written for the Universal Thread magazine and it hasn't been published yet (and I cannot published it before it is there).
PantoffelSlippersOperations Manager

Author

Commented:
Thank you Eric,

I'll watch out for it over the next few months - looking forward to it!

One last question:  if my VB solution consists of an EXE project and a DLL project.  My DLL contains all the shared functionality and also the settings (one app.config file).  These settings are contained within the appSettings section.  I use the ConfigurationManager.AppSettings.Get to retrieve the required values.

Unfortuantely, all my values are returned blank.  If the move the app.config file to the EXE I don't have this problem.  I think it's because when .Net starts an application, it creates some sort of cache from the starting application's settings.

How do I tell the ConfigurationManager to use the DLL's own app.config file?

Éric MoreauSenior .Net Consultant
CERTIFIED EXPERT
Top Expert 2016

Commented:
do you have a short code snippet to test what your saying?
PantoffelSlippersOperations Manager

Author

Commented:
Yes I do!

My solution consists of two projects:
-an exe project called AppConfigExperiment
-a DLL project called Shared.

My app.config file is part of the Shared project and for the exe project I didn't add an app.config file.

The app.config file (in the Shared project) looks like this:

(I've taken out the system.diagnostics section to make it easier to read)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
      <appSettings>
            <clear/>
            <add key="Setting1" value="Value1"/>
            <add key="Setting2" value="Value1"/>
      </appSettings>
</configuration>


My shared DLL is responsible for retrieving settings with a public function called GetSharedSetting in a class called SettingsReader.

It's code:

    Public Function GetSharedSetting(ByVal SetKey As String) As String
        Dim RetStr As String = ""

        RetStr = ConfigurationManager.AppSettings.Get(SetKey)

        Return RetStr
    End Function


The EXE project is the startup project for the solution and has one form with two text boxes and one button.  When the button is clicked, it should retrieve the two settings from the config file and populate the text boxes:

It's code:

Imports [Shared]

Public Class Form1


    Private Sub cmdLoadSettings_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdLoadSettings.Click
        Dim SR As New SettingsReader

         With Me
            .txtSetting1.Text = SR.GetSharedSetting("Setting1")
            .txtSetting2.Text = SR.GetSharedSetting("Setting2")
        End With

        SR = Nothing

    End Sub
End Class


In this example, the textboxes remain empty!!!   If I move the config file to the EXE project, it works, even though the DLL still reads it.  I'm assuming therefore that .Net creates a config cache or something from the startup application's config file....

The problem is that I've written solutions with up to 15 projects in them that inlcudes several separate EXE applications, several DLL's and several windows services.  In all cases, all the projects shared settings and I've always had a shared DLL that provides settings to any other project who requested them.  I have used my own XML files with my own code to read it which is tedious and has potential for errors.  I was hoping with the massive amount of functionality in .Net framework's configuration, I could achieve the same without writing my own stuff.

Many many thanks for the assistance!
Éric MoreauSenior .Net Consultant
CERTIFIED EXPERT
Top Expert 2016
Commented:
>>My app.config file is part of the Shared project and for the exe project I didn't add an app.config file.

The way Microsoft built the configuration file, you need to add it to the application. The compiler automatically copies it in the post build from the application folder to the bin folder.


>>In all cases, all the projects shared settings

Simply copy you App.Config from .EXE project to other. You will also discover that the name of the config file will always be YourAppName.Exe.Config
PantoffelSlippersOperations Manager

Author

Commented:
Thank you
PantoffelSlippersOperations Manager

Author

Commented:
Thank you Eric,

Please let me know once your article has been posted!
Éric MoreauSenior .Net Consultant
CERTIFIED EXPERT
Top Expert 2016

Commented:
PantoffelSlippersOperations Manager

Author

Commented:
Thank you!
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.