Click here to Skip to main content
Click here to Skip to main content
Go to top

Using the Enterprise Library (June 2005) with Visual Studio 2005

, 29 Dec 2005
Rate this:
Please Sign up or sign in to vote.
How to customize the Enterprise Library (June 2005) for Visual Studio 2005.

Introduction

In this article, I will give some hints on how to customize the Microsoft Enterprise Library (June 2005) for efficient usage with Visual Studio 2005.

The Enterprise Library was first released in January 2005 by the Microsoft Patterns and Practices team. The library includes a couple of application blocks (exception handling, logging, security, ...) which have formerly been published separately. An update of the Enterprise Library was released in June 2005. Both releases are designed and tested for the .NET Framework 1.1. The June 2005 release is also compatible with .NET 2.0 (after some minor modifications, see below), i.e. the library can be built with Visual Studio 2005 and it runs with the .NET Framework 2.0. (This is not true for the January 2005 release.)

The upcoming Enterprise Library 2.0 release, which will leverage the new capabilities of .NET 2.0, is announced and will soon be published. So why should you care about using the Enterprise Library June 2005 with Visual Studio 2005? The Enterprise Library 2.0 is not at all backwards compatible, there are significant changes to the internal architecture and the interfaces. Some application blocks which overlap with the new parts of the .NET 2.0 runtime library have been removed completely.

What I have in mind is a smooth migration of a (probably large) solution from .NET 1.1 / Enterprise Library June 2005 / Visual Studio 2003 to .NET 2.0 / Enterprise Library 2.0 / Visual Studio 2005. As part of such a migration, it does make sense to postpone the Enterprise Library June 2005 -> Enterprise Library 2.0 migration step, i.e. first to migrate an existing solution to Visual Studio 2005 while still using the Enterprise Library June 2005.

Building the Enterprise Library June 2005 with Visual Studio 2005

The basic steps to enable the Enterprise Library June 2005 to operate with Visual Studio 2005 are described in the Release Notes document which comes with the Enterprise Library June 2005:

  1. Run the Enterprise Library installation program Enterprise Library June 2005.exe. Do not select the Compile Enterprise Library option.
  2. Using Visual Studio 2005, open the solution file EnterpriseLibrary.sln. This solution file is located in the src folder of the Enterprise Library installation. When you open the solution, the Visual Studio Conversion Wizard will appear.
  3. Step through the Visual Studio Conversion Wizard and ignore any conversion errors.
  4. Replace all occurrences of the #define VS2003 string with the #define VS2005B2 string in the Enterprise Library source code.
  5. Save all the changes and close the solution.
  6. Edit the BuildLibrary.bat file. This file is located in the src folder.
  7. Change the visualStudioDir variable in the script to the path of the Visual Studio 8 installation. For example, if Visual Studio 8 is installed in the default location, change the variable to C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\.
  8. Perform the same changes in the previous step on the InstallServices.bat file. This file is located in the src folder.
  9. Run the BuildLibrary.bat, CopyAssemblies.bat, and the InstallServices.bat scripts.

I did not recognize any problems when following these basic steps. There were no conversion errors from the Visual Studio Conversion Wizard, and both the Debug and the ReleaseFinal build were only producing a small number of warnings but no errors. To summarize, what you will get from these basic migration steps is a complete set of Microsoft.Practices.EnterpriseLibrary.* assemblies plus the Enterprise Library tools (Enterprise Library Configuration Tool, Security Database Console, MSMQ Distributor), all built with Visual Studio 2005 and all running with the .NET 2.0 Framework.

The Problem: the Missing Schema

The problem arises when you try to use the Visual Studio 2005 enabled version of the Enterprise Library June 2005 in an ASP.NET 2.0 web application. As soon as you start debugging your solution in Visual Studio 2005, you will get an error like this:

Error parsing application configuration file at line xxx. 
Type '{http://www.microsoft.com/practices/enterpriselibrary/08-31-2004/
                              configuration}XmlFileStorageProviderData' 
is not found in Schema.

The suggested workaround (rename the current web.config and add a new one) does not solve the problem.

The problem does not arise if you Start Without Debugging (Ctrl+F5), or if you attach the debugger to a running w3wp process. Both workarounds are far away from being efficient.

I have not observed this error in a WinForms application, it is specific to web applications.

The Solution

Configuring the Enterprise Library Application Blocks means adding a couple of <configurationSection> elements to the web.config or app.config file. This can be done manually, but typically the web.config / app.config file is loaded into the EntLibConfig tool which is part of the Enterprise Library distribution. The tool provides a convenient user interface for editing the configuration sections.

Here's a typical example of the Enterprise Library configuration sections:

<configuration>
  <configSections>
    <section name="enterpriselibrary.configurationSettings" 
           type="System.Configuration.IgnoreSectionHandler, System, 
                Version=1.0.5000.0, Culture=neutral, 
                PublicKeyToken=b77a5c561934e089" />
  </configSections>
  <enterpriselibrary.configurationSettings 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        applicationName="Application" 
        xmlns="http://www.microsoft.com/practices/
               enterpriselibrary/08-31-2004/configuration">
    <configurationSections>
      <configurationSection name="dataConfiguration" 
                               encrypt="false">
        <storageProvider xsi:type="XmlFileStorageProviderData" 
             name="XML File Storage Provider" 
             type="Microsoft.Practices.EnterpriseLibrary.
                   Configuration.Storage.XmlFileStorageProvider, 
             Microsoft.Practices.EnterpriseLibrary.Configuration" 
             path="dataConfiguration.config" />
          <dataTransformer xsi:type="XmlSerializerTransformerData" 
             name="Xml Serializer Transformer" 
             type="Microsoft.Practices.EnterpriseLibrary.
                     Configuration.Transformer.XmlSerializerTransformer, 
                   Microsoft.Practices.EnterpriseLibrary.Configuration">
          <includeTypes />
        </dataTransformer>
      </configurationSection>
    </configurationSections>
    <keyAlgorithmStorageProvider xsi:nil="true" />
  </enterpriselibrary.configurationSettings> 
</configuration>

Each <configurationSection> associated with the XML File Storage Provider is usually referencing a satellite configuration file (dataConfiguration.config in the sample). In a large project, there might be dozens of <configurationSection> elements with associated satellite configuration files.

While debugging an ASP.NET application in Visual Studio 2005, the parser cannot resolve the URI: xmlns="http://www.microsoft.com/practices/enterpriselibrary/08-31-2004/configuration" and triggers the error mentioned above.

The solution is quite simple:

Move all of the Enterprise Library configuration sections out of the web or app configuration files into a separate Enterprise Library main configuration file. The Enterprise Library main configuration file is referenced by an <appSettings> key in the web / app configuration file:

<appSettings>
   <add key="entLibConfigFile" 
      value="Config\enterpriseLibrary.config"/>
</appSettings>

This introduces two levels of redirection when looking for Enterprise Library configuration settings: follow the entLibConfigFile key to the Enterprise Library main configuration file, then (if the requested <configurationSection> is associated with the XML File Storage Provider) follow the path to the satellite configuration file. In the example, the Enterprise Library main configuration file is called enterpriseLibrary.config and is expected in a subfolder named config relative to the location of the web / app configuration file.

The Enterprise Library Configuration Application Block caches configuration sections internally. So, following the twofold redirection is only necessary when reading a configuration section for the first time.

Instead of web.config / app.config, the Enterprise Library main configuration file is the one you will load into the EntLibConfig tool for editing. In fact, following this approach, web.config / app.config must no longer be loaded by EntLibConfig.

Using the EntLibConfig tool, you have the free choice to open any .NET configuration file for editing. But if you request a configuration section in code by calling Microsoft.Practices.EnterpriseLibrary.Configuration. ConfigurationManager.GetConfiguration(), the Enterprise Library will automatically load the application configuration file (web.config / app.config). The same is true if you call any Enterprise Library method which is implicitly loading a configuration section, e.g. ExceptionPolicy.HandleException().

So, implementing the first level of redirection requires some small modifications of the Enterprise Library sources and a rebuild of the Enterprise Library.

Open the EnterpriseLibrary.sln solution file in Visual Studio 2005 and have a look at the ConfigurationBuilder.cs class file which is part of the Configuration project. The key is the private method LoadMetaConfiguration() which is called whenever a configuration section is about to be loaded, no matter if the request comes from opening a file in EntLibConfig or from calling ConfigurationManager.GetConfiguration() in code.

Add this line of code as the first line of the LoadMetaConfiguration() body:

configurationFile = ConfigurationFilePicker.Lookup(configurationFile, 
                                           MachineConfigurationFile);

With this small modification, the whole method looks like this:

private void LoadMetaConfiguration(string configurationFile)
{
  configurationFile = ConfigurationFilePicker.Lookup(configurationFile, 
                                             MachineConfigurationFile);

  configFile = new ConfigurationFile(configurationFile, null);
  string machineFilename = MachineConfigurationFile;
  // make sure we don't load the machine file twice
  if (string.Compare(configurationFile, machineFilename, 
             true, CultureInfo.InvariantCulture) != 0)
  {
    ConfigurationFile machineConfigFile = 
            new ConfigurationFile(machineFilename, null);
    configFile = new ConfigurationFile(configurationFile, 
                                      machineConfigFile);
  }

  CreateMetaConfigChangeWatcher();

  this.currentConfigFileName = configurationFile;
  InitializeConfiguration(ReadMetaConfiguration());
}

The ConfigurationFilePicker class is available for download following the download source link at the beginning of this article. Copy the downloaded ConfigurationFilePicker.cs file to the root folder of the Configuration project (src/Configuration). Then add the file to the Configuration project. Further, add a reference to System.Configuration to the Configuration project.

The ConfigurationFilePicker class has a single static method Lookup():

public static string Lookup(string configurationFile, 
                            string machineConfigurationFile)
{
  // EntLibConfig tool is allowed to load any configuration file.
  // So check whether EntLibConfig is the process executable.
  // Hint: If GetEntryAssembly() returns null,
  //       there is no process executable in the default
  // application domain (e.g. for ASP.NET web applications).
  // In this case, we are clearly not
  // running EntLibConfig.
  if (Assembly.GetEntryAssembly() != null)
  {
    if (string.Compare(Assembly.GetEntryAssembly().GetName().Name, 
        "EntLibConfig", true, CultureInfo.InvariantCulture) == 0)
      return configurationFile;
  }

  // Machine.config file must not be loaded as main configuration file.
  if (string.Compare(configurationFile, machineConfigurationFile, 
                        true, CultureInfo.InvariantCulture) == 0)
    throw new ConfigurationErrorsException("Loading machine.config" + 
               " as main configuration file is not supported here.");

  // Retrieve entLibConfigFile key from appsettings.
  NameValueCollection appSettings = 
         System.Configuration.ConfigurationManager.AppSettings;
  string entLibConfigFile = appSettings.Get("entLibConfigFile");
  if (entLibConfigFile == null)
    throw new ConfigurationErrorsException("Unable to find" + 
            " entLibConfigFile key in appSettings section.");

  // Retrieve path of application / web configuration file.
  string appConfigFile = 
     AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
  string appConfigPath = Path.GetDirectoryName(appConfigFile);
  if (!appConfigPath.EndsWith(@"\")) appConfigPath += @"\";

  // entLibConfigFile is appended to appConfigPath.
  if (entLibConfigFile.StartsWith(@"\"))
     entLibConfigFile = entLibConfigFile.TrimStart(@"\".ToCharArray());
  return appConfigPath + entLibConfigFile;
}

The method gets the configuration file the Configuration Application Block is about to load and redirects it to the configuration file we want to load.

First, we check whether we are called by the EntLibConfig tool. In this case, there is no redirection, i.e. the EntLibConfig tool is still allowed to open any configuration file (the user has chosen to open). Then we read the entLibConfigFile key from the appSettings section. Here, the name and the path of our Enterprise Library main configuration file is expected relative to the path of the application configuration file (web.config / app.config); the value of the entLibConfigFile key is appended to this path.

You can give this approach a first try with the Security Database Console which comes with the Enterprise Library:

  1. Having EnterpriseLibrary.sln still open in Visual Studio 2005, set Tools.SecurityDatabaseConsole to be the startup project.
  2. Add a new folder named Config to the Tools.SecurityDatabaseConsole project.
  3. Add a new application configuration file named enterpriseLibrary.config to the Config folder.
  4. Move both the <configSections> and the <enterpriselibrary.configurationSettings> elements (with all sub-elements) from app.config to enterpriseLibrary.config.
  5. Move all the satellite configuration files (dataConfiguration.config, securityConfiguration.config, securityCryptographyConfiguration.config) from the root folder to the Config folder.
  6. Add a <appSettings> section to the app.config redirecting to the Enterprise Library main configuration file:
    <appSettings>
       <add key="entLibConfigFile" 
              value="Config\enterpriseLibrary.config"/>
    </appSettings>
  7. Open the Properties editor of the Tools.SecurityDatabaseConsole project. Add a new command to the Post-build event command line:
    copy "$(ProjectDir)*.manifest" "$(TargetDir)" > nul
    copy "$(ProjectDir)\*.config" "$(TargetDir)" > nul
    xcopy "$(ProjectDir)config\*.config" "$(TargetDir)config\" /Y /R

    Of course, the Security Database Console (as a WinForms application) would have run in the Visual Studio 2005 debugger without our modifications. The real interesting test is to reference the customized Enterprise Library in an ASP.NET application to see that the annoying error is gone. Also, some people might consider it to be more transparent to have the Enterprise Library configuration stuff out of the application configuration file.

Links

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Michael Schmitt
Architect
Germany Germany
Michael is working with programming technologies since the beginning of the nineties. His main interest is in Microsoft .NET and BizTalk Server.

Comments and Discussions

 
QuestionHow to configure and use Microsoft Enterprise Library 5 for logging PinmemberLibish Varghese Jacob17-Jul-12 20:15 
QuestionMissing class for changes Pinmemberlimitzero28-Jun-07 12:12 
AnswerRe: Missing class for changes PinmemberMichael Schmitt29-Jun-07 6:48 
GeneralExcellent! PinmemberD Fay4-Jun-07 10:26 
GeneralThank You So Much PinmemberPinhead_Me1-Apr-07 8:19 
GeneralGood!!! Pinmemberi.Posei10-Aug-06 5:18 
GeneralExcellent work Pinmemberserdar2nc19-Apr-06 19:46 
GeneralInvalid section name PinmemberAkemi1112-Jan-06 8:27 
GeneralRe: Invalid section name PinmemberMichael Schmitt12-Jan-06 10:13 
GeneralRe: Invalid section name Pinmembergman_il26-Mar-06 23:16 
GeneralRe: Invalid section name PinmemberMichael Schmitt27-Mar-06 2:28 
GeneralRe: Invalid section name [modified] Pinmemberalex_graham31-May-06 5:25 
GeneralRe: Invalid section name [modified] PinmemberMichael Schmitt31-May-06 6:43 
GeneralRe: Invalid section name [modified] Pinmemberalex_graham1-Jun-06 3:16 
GeneralRe: Invalid section name [modified] PinmemberMichael Schmitt1-Jun-06 6:19 
Generalummm noo Funcaa Pinmembermascodigo12-Jan-06 7:45 
GeneralSoooo amazing! Pinmemberychapados12-Jan-06 3:04 
JokePerfect! Pinmemberultraplex4110-Jan-06 0:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140916.1 | Last Updated 29 Dec 2005
Article Copyright 2005 by Michael Schmitt
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid