Enterprise Library 5.0 and backward compatibility

Topics: Caching Application Block , Data Access Application Block
Jul 12, 2012 at 1:33 PM

I am developing a new project (using enterprise library 5.0) which needs a dll (source code unavailable) that is using (referenced in the project) enterprise library 2.0. As we cannot have multiple version of the same dll in the bin directory we are facing issues. Even if I use Enterprise Library 5.0 the code part (dll for which source code isn't available) using enterprise library 2.0 is throwing errors that it cannot load the relevant assemblies.

Another constraint is that we cannot deploy the Enterprise Library to GAC because of policy restriction of the hosting company. Is there a solution for this issue? 

Editor
Jul 12, 2012 at 4:58 PM

You can use a custom assembly resolver to load the Enterprise Library 2 assemblies.

First, I would deploy the Enterprise Library 2 assemblies to a subdirectory under your application folder.  For example, "bin\debug\EntLib2".  So, the Enterprise Library assemblies will be in the EntLib2 directory.  Next create a custom resolver to load the assemblies:

    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(Custom_Resolve);
    }

    private static Assembly Custom_Resolve(object sender, ResolveEventArgs args)
    {
        // variety ways of getting current directory (e.g. System.Reflection.Assembly.GetExecutingAssembly()
        // Location or Codebase some might work depending or not on the context.  For example, shadow copying may impact
        // these paths.) This can be saved in a static variable for reuse.
        string baseDirectory = Path.GetDirectoryName(
            System.Reflection.Assembly.GetExecutingAssembly().Location
            );
        string searchDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "EntLib2");
            
        var assemblyInfo = args.Name.Split(',');
        string assemblyName = assemblyInfo[0] + ".dll";

        string assemblyFile = Path.Combine(searchDirectory, assemblyName);
        if (File.Exists(assemblyFile) && AssemblyName.GetAssemblyName(assemblyFile).FullName == args.Name) 
        {
            return Assembly.LoadFile(assemblyFile);
        }

        return null; 
    }

Now if the assembly cannot be resolved and it matches the assembly definition in the EntLib2 directory that assembly will be loaded.

I don't think .NET configuration can be used because the assemblies will have different strong names.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Jul 13, 2012 at 6:47 AM

Thanks a lot for the reply,

The application I am developing in a web application. I have created the event handler in Master Page Page_Load Event. While debugging i am not able to see it looking for Enterprise Library 2.0 dll. I it because the EL 2.0 is referenced within a dll to which we don't have the source code?

Editor
Jul 14, 2012 at 6:34 AM

If you are developing a web application, I would add the custom resolver registration to the global.asax in Application_OnStart so it just happens once.

You should be able to debug your code no matter what assemblies are being resolved.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Jul 17, 2012 at 2:29 PM

I have added the code in Application_OnStart in global.asax. I am still getting the same error. When i Debug it is looking for some dll System.web.resources but never looked for EL 2.0 DLLs (Microsoft.Practices.EnterpriseLibrary.Common.dll and Microsoft.Practices.EnterpriseLibrary.Data.dll). I even added a reference in web.config in config section which did not work. Looking forward to you suggestions.

Editor
Jul 17, 2012 at 10:59 PM

That sounds strange.  What is the exact error message that you are getting?  I would expect to see something like: "Could not load file or assembly 'Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)".

I would recommend using Fuslogvw.exe (Assembly Binding Log Viewer) to log the assembly binds and see what assemblies are not loading.

If you are using ASP.NET I would place the assemblies in it's own subdirectory off the web root and amend the code to: 

        private static Assembly Custom_Resolve(object sender, ResolveEventArgs args)
        {
            string searchDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "EntLib2");

            var assemblyInfo = args.Name.Split(',');
            string assemblyName = assemblyInfo[0] + ".dll";

            string assemblyFile = Path.Combine(searchDirectory, assemblyName);
            if (File.Exists(assemblyFile) && AssemblyName.GetAssemblyName(assemblyFile).FullName == args.Name)
            {
                return Assembly.LoadFile(assemblyFile);
            }

            return null;
        }

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Jul 18, 2012 at 11:28 AM

Thanks a lot. It worked. Thank you once again.