views:

113

answers:

3

I'm storing my application settings in my web.config file and accessing them using ConfigurationManager.GetSection or ConfigurationManager.AppSettings. I've created a test to ensure that the settings I'm getting from my class are the correct settings in the web.config file, however, it's returning null values. How can I tell my unit test that the class library should be using the web.config file for it's configuration rather than the app.config file that accompanies the class library? In this case since I'm generating a quick test, I'm using the built-in VS Unit test library.

A: 

In your app.config file, you could add the "file" attribute to your appSettings element:

<appSettings file="d:\mydir\web.config">

I'm not endorsing this as a best practice but it will cause your app.config to inherit the appsettings of your web.config.

Matt Wrock
I've tried adding an app.config file to the class library, adding in my custom configuration section, and adding in the attribute to the sectionGroup to point to the web.config file, however, it still generates nulls.When the web application runs, I do get the expected results though.
Jason N. Gaylord
ok. yeah. the file attribute only works for appSettings and not for other custom sections.
Matt Wrock
No problem. Any other ideas?
Jason N. Gaylord
A: 

Pretty lengthy but try this:

using System;
using System.Configuration;
using System.Web;
using System.Web.Caching;
using System.Xml;
using System.Xml.Serialization;

namespace Sol3.Configuration
{
    //######################################################################################################################################################
    /// <summary>
    /// This creates a configuration section handler letting the system know that any object with a 
    /// typeof(ClientConfiguration) can tie directly to the config file and section.
    /// </summary>
    public class ClientSetupSerializerSectionHandler : IConfigurationSectionHandler
    {
        public object Create(object parent, object configContext, System.Xml.XmlNode section)
        {
            XmlSerializer ser = new XmlSerializer(typeof(Sol3.Configuration.ClientSetupConfiguration));

            return ser.Deserialize(new XmlNodeReader(section));
        }
    }
    //######################################################################################################################################################
    /// <summary>
    /// This is the concrete class that will handle the "ClientHandler" section in the web.config.
    /// </summary>
    [Serializable()]
    [XmlRoot("BasicSetup")]
    public class ClientSetupConfiguration
    {
        #region Properties
        [XmlElement("HomePageRedirect")] public string HomePageRedirect;
        [XmlElement("ServicesRootUrl")] public string ServicesRootUrl;
        [XmlElement("CookieDomain")] public string CookieDomain;
        [XmlElement("AllowScriptAccess")] public string AllowScriptAccess;
...
        [XmlElement] public string Info_Server;
        [XmlElement] public string Info_Database;
        #endregion

        #region Static Methods
        public static ClientSetupConfiguration GetSetupConfig()
        {
            if (HttpContext.Current.Cache["ClientSetupConfiguration"] == null)
                HttpContext.Current.Cache.Insert("ClientSetupConfiguration", ConfigurationManager.GetSection("BasicSetup"));

            return (Sol3.Configuration.ClientSetupConfiguration)HttpContext.Current.Cache["ClientSetupConfiguration"];
        }
        #endregion
    }
}

I then created a "helper" class that looks like this:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Sol3    {
    static class AppSettings
    {
        public static string Info_Server { get { return Sol3.Configuration.ClientSetupConfiguration.GetSetupConfig().Info_Server; } }
        public static string Info_Database { get { return Sol3.Configuration.ClientSetupConfiguration.GetSetupConfig().Info_Database; } }
...
        static public bool inProduction { get { return Info_Server.ToLower().Contains("rackspace"); } }

    }
}

Now, from anywhere in code I can call Sol3.AppSettings.Info_Server and it gets that info from the web.config.

This is all done in a DLL project and has been working for us for quite awhile now. The GetSetupConfig() is key as this is how it knows to get the web.config file...

HTH

Keith Barrows
Well, my code works, but when testing, the test project doesn't know which configuration file to pull from. How does this know before runtime to pull from the web.config?
Jason N. Gaylord
Hmm, good question. I've not tried this code in that situation. You can see if there is anything in my blog post on using multiple configs - http://sol3.net/blogs/starpilot/archive/2008/04/21/using-multiple-config-files-in-one-application.aspx.
Keith Barrows
A: 

I was able to add the app.config file to the Tests application to get my issue resolved.

Jason N. Gaylord
In fact, even modifying my app.config and removing that section, it worked. The underlying issue was that an attribute was failing somewhere else in the web.config, so it wasn't working.
Jason N. Gaylord