Share via


Avoiding configuration pitfalls with incompatible copies of Enterprise Library

When you install Enterprise Library 3.0, you actually get two distinct copies of the library. One copy is in the form of pre-compiled binaries - by default these get installed to "C:\Program Files\Microsoft Enteprise Library 3.0 - April 2007\bin". The other copy is in the form of source code, which by default will be compiled and the assemblies coped to "C:\EntLib3Src\App Blocks\bin".

While both copies of Enterprise Library contain identical code, there is one critical difference: the pre-compiled binaries are strong-named (with a Microsoft key that we do not ship), and the assemblies compiled from the source code are not initially strong-named. So as far as .NET is concerned, these two sets of assemblies are completely different and completely incompatible with one another. This is standard .NET behavior, and could cause problems with previous versions of EntLib (and your own projects) if you keep multiple copies with different strong-name identities around - but since for the first time we are shipping both copies in the same "box", this is understandably causing some confusion for quite a few people.

The likelihood of issues is compounded by the fact that an application using Enterprise Library will typically contain binary references to EntLib assemblies, as well as configuration files that refer to a specific copy of Enterprise Library assemblies. Typically you won't edit the configuration files by hand, so the copy of the assemblies referenced in your configuration files will be determined by which copy of the configuration tool you use. If there is not a perfect match between the assemblies referenced from the binaries, the ones defined in configuration, and the ones actually located on disk, strange things can happen, such as the following:

  • If you use the configuration tool to load an existing configuration file that references a different copy of the assemblies to the ones the tool knows about, you will receive an error dialog "One or more errors occurred while trying to open the configuration", and a list of configuration errors such as "Could not load file or assembly 'Microsoft.Practices.EnterpriseLibrary.Data, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The located assembly's manifest definition does not match the assembly refernece".
  • If you use the configuration tool to add a custom provider to a block's configuration, and the provider was compiled against a different copy of the assemblies to the one the tool knows about, you will receive an error when trying to browse for the providers in that assembly along the lines of "There were no types found in the assembly 'ValidationQuickStart.CustomValidators' that implement or inherit from the base type 'Microsoft.Practices.EnterpriseLibrary.Validation.Validator'"
  • If you attempt to run an application that uses Enterprise Library, but the application's configuration file was saved with a copy of the configuration tool that uses a different copy of the assemblies to the assemblies referenced by the application, you will receive exceptions such as "System.Configuration.ConfigurationErrorsException: An error occurred creating the configuration section handler for enterpriseLibrary.ConfigurationSource: Could not load file or assembly 'Microsoft.Practices.EnterpriseLibrary.Common, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference."

The good news is that all of these problems can be avoided easily enough if you keep a few things in mind. First, you need to decide which copy of Enterprise Library you want to use in your application. Using the precompiled, strong-named binaries usually provides the path of least resistance, although it has a significant limitation in that you do not have the ability to make changes to the code and recompile it to a compatible version of the assembly. Using a copy compiled from the source code requires you (or your team) to take more responsibility for the code, but also gives you more flexibility since you can make changes more easily. Neither option is inherently right or wrong (which is why we give you both), however you should make conscious decision on which ones make sense for you. It may be a good idea to purge your system of whatever sets of binaries you decided against using to minimize confusion.

Once you've decided which binaries to use, you should obviously always reference these in your projects, including any projects containing custom Enterpirse Library extensions. The Enterprise Library assemblies listed on the ".NET" tab in Visual Studio's References dialog are the strong-named ones, so if you want to use a different version you should navigate to these in the "Browse" tab.

Next, you need to make sure you edit configuration files using a copy of the Enterprise Library Configuration tool that knows about the same copy of the assemblies as your app, since it will use these to generate your configuration files. If you are using the external configuration tool (EntLibConfig.exe), you should simply use a copy of the tool compiled against the same set of assemblies (i.e. in the same "bin" directory). Note that the Start Menu shortcut that installs with Enterprise Library 3.0 points to the copy in "C:\Program Files\Microsoft Enteprise Library 3.0 - April 2007\bin" which uses the strong-named assemblies. If you want to use the non-strong-named one, you'll need to navigate to the "C:\EntLib3Src\App Blocks\bin" folder yourself (or update the Start Menu shortcut).

Things are a little more interesting if you are using the Visual Studio-integrated Configuration Editor, since you can't install multiple copies of Visual Studio. By default, the Configuration Editor will use the strong-named Enterprise Library assemblies. However it is possible to redirect the tool to a different set of assemblies on a per-solution basis. To do this, open a solution, select the solution root node in the Solution Explorer and then look at the Properties window. You should see a property called EnterpriseLibraryConfigurationSet. By default, this will contain the options "(Machine default)", "Microsoft Signed" and "EntLib3Src". Selecting "EntLib3Src" will tell the tool to use the assemblies from "C:\EntLib3Src\App Blocks\bin" for editing any configuration files in this solution. Note that we set the EnterpriseLibraryConfigurationSet to "EntLib3Src" for all of our QuickStart applications, since they are compiled against the source code projects. If you want to add, edit or remove the "configuation sets" or change the default, this information is stored in the registry in HKEY_CURRENT_USER\Software\Microsoft\Practices\EnterpriseLibrary\ConfigurationEditor (for per-user settings) and HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\Packages\{488366a4-630c-4a0e-a6a2-b019cee13bea}\ConfigurationEditor (for machine-wide settings).

One final note - if you or your organization has chosen to strong-name Enterpirse Library with your own key pair (which is a very common scenario), there are even more opportunities for assembly-mismatch problems to occur since you may have 3 or more incompatible sets of assemblies. However the priniciples for keeping everything matching are exactly the same as described above.