Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Application Configuration for different environments

Posted on 2009-02-15
20
Medium Priority
?
1,482 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
0
Comment
Question by:PantoffelSlippers
  • 11
  • 8
20 Comments
 
LVL 70

Accepted Solution

by:
Éric Moreau earned 900 total points
ID: 23645003
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)

0
 

Author Comment

by:PantoffelSlippers
ID: 23645062
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
0
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 23645198
>>- 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.
0
Get quick recovery of individual SharePoint items

Free tool – Veeam Explorer for Microsoft SharePoint, enables fast, easy restores of SharePoint sites, documents, libraries and lists — all with no agents to manage and no additional licenses to buy.

 
LVL 27

Assisted Solution

by:nmarun
nmarun earned 100 total points
ID: 23645286
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
0
 

Author Comment

by:PantoffelSlippers
ID: 23646175
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
0
 

Author Comment

by:PantoffelSlippers
ID: 23646190
Thanks nmarun,

I'll have a look and post back
0
 
LVL 70

Assisted Solution

by:Éric Moreau
Éric Moreau earned 900 total points
ID: 23646435
You will need to inherit the ConfigurationSection class. See http://msdn.microsoft.com/en-us/library/system.configuration.configurationsection.aspx
0
 

Author Comment

by:PantoffelSlippers
ID: 23651630
Eric,

Does this apply to desktop applications as well?
0
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 23652027
yes and it is exactly the same code.
0
 

Author Comment

by:PantoffelSlippers
ID: 24095287
Yes OK it looks as if ConfigurationSections might be my answer - I'm just strangely having difficulty making it work!
0
 

Author Comment

by:PantoffelSlippers
ID: 24125030
Eric,

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

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

Thanks!
0
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 24125118
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).
0
 

Author Comment

by:PantoffelSlippers
ID: 24126061
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?

0
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 24127270
do you have a short code snippet to test what your saying?
0
 

Author Comment

by:PantoffelSlippers
ID: 24128448
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!
0
 
LVL 70

Assisted Solution

by:Éric Moreau
Éric Moreau earned 900 total points
ID: 24129664
>>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
0
 

Author Closing Comment

by:PantoffelSlippers
ID: 31547075
Thank you
0
 

Author Comment

by:PantoffelSlippers
ID: 24277931
Thank you Eric,

Please let me know once your article has been posted!
0
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 24279894
0
 

Author Comment

by:PantoffelSlippers
ID: 24280225
Thank you!
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
In real business world data are crucial and sometimes data are shared among different information systems. Hence, an agreeable file transfer protocol need to be established.
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
As many of you are aware about Scanpst.exe utility which is owned by Microsoft itself to repair inaccessible or damaged PST files, but the question is do you really think Scanpst.exe is capable to repair all sorts of PST related corruption issues?

577 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question