Java Mailing List Archive

http://www.gg3721.com/

Home » the NHibernate development list »

[NHibernate-development] Mapping configuration for types from
 already loaded assemblies (bug and fix).

Gena

2008-05-10

Replies: Find Java Web Hosting

Author LoginPost Reply
Dear all,

It looks like I found another problem in the NHibernate (and fix). I have application assemblies containing mapping files are located in the different folders and pre-loaded as plugins and it seems that NHibernate does not like it. Everything works nice in a unit test but NHibernate throws an error in the working application. Here is my situation:

Scenario 1, tests, works fine:

Test/bin/Debug/
     AppTests.dll
     NHibernateDao.dll............................ adds all mappings from all configured libraries
     Plugin1.dll....................................... contains some hbm.xml files
     Plugin2.dll
     ...
     

Scenario 2, deployed application, *crashes*:

App/
   bin/
      App.exe................................. loads all plugins and then initializes NHibernateDao (which is also one of plugins)
      plugins/
         NHibernateDao/
            NHibernateDao.dll.................. here it tries to add all mappings from configured assemblies and then crashes
         Plugin1/
            Plugin1.dll
         Plugin2/
            Plugin2.dll
        
All my assemblies are already loaded a a plugins and inside NHibernateDao.dll I add mapping for all my assemblies using:

                    cfg = cfg.AddAssembly(assembly);

The reason why NHibernate crashes is because duruing configuration of hbm.xml files Binder tries to load assemblies from the current directory even when they are already loaded in the current Application Domain. Binder.cs calls ReflectHelper.cs when it needs to load configured type in the following way:
   
Binder.cs:
        protected static System.Type ClassForFullNameChecked(string fullName, string errorMessage)
        {
            try
            {
                return ReflectHelper.ClassForName(fullName);
            }
            catch (Exception e)
            {
                throw new MappingException(String.Format(errorMessage, fullName), e);
            }
        }

ReflectHelper.cs:
        public static System.Type ClassForName(string name)
        {
            AssemblyQualifiedTypeName parsedName = TypeNameParser.Parse(name);
            System.Type result = TypeFromAssembly(parsedName, true);
            return result;
        }

        public static System.Type TypeFromAssembly(AssemblyQualifiedTypeName name, bool throwOnError)
        {
            try
            {
                ...
                // crashes here because assemblies loaded in the current AppDomain are not taken into account!
                Assembly assembly = Assembly.Load(name.Assembly);
                ...
            ...
        }

As result NHibernate is unable to configure assemblies which are already loaded. It seems to be easy to fix and it looks like such a feature will be nice to have in NHibernate.

---------------------------

Suggested PATCH for current trunk:

Extend ReflectHelper.TypeFromAssembly to take into account assemblies already loaded in the current AppDomain.

Index: ReflectHelper.cs
===================================================================
--- ReflectHelper.cs    (revision 3477)
+++ ReflectHelper.cs    (working copy)
@@ -257,6 +257,20 @@
                                        return null;
                                }

+                           // try to get type from the current AppDomain first
+                           Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
+                           foreach(Assembly loadedAssembly in loadedAssemblies)
+                           {
+                                  if(loadedAssembly.GetName().Name.Equals(name.Assembly))
+                                  {
+                                        type = loadedAssembly.GetType(name.Type, throwOnError);
+                                        if(type != null)
+                                        {
+                                            return type;
+                                        }
+                                   }
+                              }
+
                                Assembly assembly = Assembly.Load(name.Assembly);

                                if (assembly == null)


--
Best regards,
Gena
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Nhibernate-development mailing list
Nhibernate-development@(protected)
https://lists.sourceforge.net/lists/listinfo/nhibernate-development
©2008 gg3721.com - Jax Systems, LLC, U.S.A.