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.
Comments
Anonymous
April 19, 2007
Tom, Thanks for the info this is exactly what I needed. One question though, due to your final note, I am wondering if there is any benefit in keeping the MS Signed assemblies around? I found that by replacing the pre-compiled binaries with my own strong named solved the editor issues. Is there any reason not to do this? ThanksAnonymous
April 19, 2007
If you don't plan on using the signed assemblies, there is no reason to keep them on your machine. And if you later change your mind, you can always just reinstall EntLib to get them back!Anonymous
April 20, 2007
Tom - this is brilliant. I must have spent 4/5 hours on this a couple of days ago. Solved in 30 seconds after reading your article! Thanks Heaps Al.Anonymous
April 21, 2007
Here is something related. http://www.codeplex.com/entlib/Thread/View.aspx?ThreadId=9240 Is there an application to do an update of the config where one would supply the new version of the EntLibConfig and then have the .config files upgraded to that version and public key with out having to hand edit the file? If build the config with out a signed library, then I swith what would I need to do to upgrade the config files? If I start with the c:program files then switch to my own how would that be done? Would all this be done by hand? Thank for the registry setting and stuff that helps.Anonymous
April 23, 2007
Even though the Validation Application Block supports extensive composition of validation rules (usingAnonymous
April 26, 2007
Although I fully understand the path you took, it does cause some headaches if you have to change from using the precompiled libraries to your own compiled versions at a later time. In our case, we found a minor bug with a policy injection call handler that wasn't marked as serializable. To fix the problem in code took 2 seconds, battling the incompatibilities across the applications that had already been written against the original version took considerably longer. Some thoughts might be that during the install decide which version to use for the default location (signed or unsigned) or perhaps an option to create a signed version with a key of our choosing during the install?Anonymous
April 29, 2007
Hello, how can i resolve this problem : Package Load Failure Package 'Microsoft.Practices.EnterpriseLibrary.Configuration.Design.VisualStudioIntegration.EnterpriseLibraryIntegrationPackage, Microsoft.Practices.EnterpriseLibrary.Configuration.Design.VisualStudioIntegration, Version=3.0.0.0, Culture=neutral, PublicToken=b03f5f7f11d50a3a' has failed to load properly ... ThanksAnonymous
May 02, 2007
Tom - I thought my problems related to this issue were solved, but they seemed to have resurfaced following my introduction of the Asynchronous Splash Screen (also found on codeplex) to my solution. I find that I am forced to drop the /2.0 portion of the ProfileCatalog.xml namespace to enable the async splash screen work otherwise an error occurs whilst deep down in the CAB framework whilst enumerating through the modules. If I remove the /2.0 all is well and the splash screen works, but I then find that I cannot use the Enterprise Library Configuration tool because it must validate the XML. I'm not sure how to resolve this issue. Is there someone/somewhere that I can refer to, (beside wading through the internals of CAB) to better understand what is happening here? Regards Al.Anonymous
May 23, 2007
I just upgrade from Ent Lib 2.0to Ent Lib 3.0 and Vista. I have deleted all the Ent Lib 2.0 .dlls from my bin folder in my web project and added the new 3.0 .dlls from the D:EntLib3SrcApp Blocksbin. It actually installed the source on my d: drive. Also I am using the EntLibconfig tool from the D:EntLib3SrcApp Blocksbin folder as well. I used the assemblies from "C:EntLib3SrcApp Blocksbin" for editing any configuration files in my solution. When I build the website I get the following error messages: Error 3 'Microsoft.Practices.EnterpriseLibrary.Caching.CacheManager' does not contain a definition for 'RemoveItemsFromCache' D:_SYL_ProjectProjectsShareYourLossBLLFAQ.cs 224 26 BLL It worked with Ent Lib 2.0 but now everytime I run it I get the above error. I have delete all leftovers from Ent Lib 2.0 and all the old .dlls I could find. When I click on “Go to definition” it takes me to a file called CacheManager(from Metadata) and that file only has the method signatures in there. The method signture for my “RemoveItemsFromCache” is missing. Can somebody tell me what is going on??? Thanks, NewbieAnonymous
May 30, 2007
I am giving a lecture about Enterprise Library 2.0 and 3.0 for a customer later this month, and spendingAnonymous
June 18, 2007
Thanks so much for this clarification. Spent all day battling that error and read this and it was fixed in 30 seconds.