how to fix this strange error regarding NHibernate inside Unity?

Hi all,

I am trying to setup a Unity app to connect to a MySQL database via NHibernate. I added to the Assets/Libs the following DLLs, taken both from the official NHibernate 3.0 binaries and the Mono runtime GAC repository:

  • Antlr3.Runtime
  • Castle.Core
  • Iesi.Collections
  • log4net
  • mysql.data
  • NHibernate
  • NHibernate.ByteCode.Castle
  • Remotion.Data.Linq
  • System.Configuration
  • System.Data
  • System.Data.DataSetExtensions
  • System.Xml
  • System.Xml.Linq
  • an assembly with data objects suitable for NHibernate

I changed, in Player Settings, the API compatibility level from ".NET 2.0 Subset" to ".NET 2.0" to allow the project to use all assemblies referenced internally by the NHibernate dlls.

I use the following code at the beginning of the Start method of a C# script attached to the main camera of the scene:

        // Configuring Log4Net
        XmlConfigurator.Configure(new FileInfo(@"log4net.config"));

        // NHibernate
        if (Log.IsDebugEnabled) {
            Log.DebugFormat("BaseDirectory[{0}] RelativeSearchPath[{1}]", AppDomain.CurrentDomain.BaseDirectory, AppDomain.CurrentDomain.RelativeSearchPath);
        }
        var cfg = new NHibernate.Cfg.Configuration();
        cfg.Configure();
        cfg.AddAssembly(typeof (User).Assembly);
        sessionFactory = cfg.BuildSessionFactory();

        var schema = new SchemaExport(cfg);
        schema.Create(true, false);

I have the log4net.config and the hibernate.cfg.xml in the root directory of the project, where they are visible and supposedly local for both the generated executable that is deployed there and the Unity3D IDE. But when starting my app, i get a strange error:

ArgumentNullException: Argument cannot be null.

Parameter name: type
  at System.Activator.CheckType (System.Type type) [0x00000] in <filename unknown>:0

  at System.Activator.CreateInstance (System.Type type, Boolean nonPublic) [0x00000] in <filename unknown>:0

  at System.Activator.CreateInstance (System.Type type) [0x00000] in <filename unknown>:0

  at NHibernate.LoggerProvider.GetLoggerFactory (System.String nhibernateLoggerClass) [0x00000] in <filename unknown>:0
Rethrow as ApplicationException: Unable to instantiate: 
  at NHibernate.LoggerProvider.GetLoggerFactory (System.String nhibernateLoggerClass) [0x00000] in <filename unknown>:0 

  at NHibernate.LoggerProvider..cctor () [0x00000] in <filename unknown>:0
Rethrow as TypeInitializationException: An exception was thrown by the type initializer for NHibernate.LoggerProvider
  at NHibernate.Cfg.Configuration..cctor () [0x00000] in <filename unknown>:0
Rethrow as TypeInitializationException: An exception was thrown by the type initializer for NHibernate.Cfg.Configuration
  at Main.Start () [0x00042] in D:\Projects\aa_ed\ZoneServer\Assets\Main.cs:36

(Filename: Assets/Main.cs Line: 36)

The problem lies in the following function inside the class NHibernate.LoggerProvider:

        private static string GetNhibernateLoggerClass()
        {
            var nhibernateLogger = ConfigurationManager.AppSettings.Keys.Cast<string>().FirstOrDefault(k => NhibernateLoggerConfKey.Equals(k.ToLowerInvariant()));
            string nhibernateLoggerClass = null;
            if (string.IsNullOrEmpty(nhibernateLogger))
            {
                // look for log4net.dll
                string baseDir = AppDomain.CurrentDomain.BaseDirectory;
                string relativeSearchPath = AppDomain.CurrentDomain.RelativeSearchPath;
                string binPath = relativeSearchPath == null ? baseDir : Path.Combine(baseDir, relativeSearchPath);
                var log4NetDllPath = Path.Combine(binPath, "log4net.dll");

                if (File.Exists(log4NetDllPath))
                {
                    nhibernateLoggerClass = typeof (Log4NetLoggerFactory).AssemblyQualifiedName;
                }
            }
            else
            {
                nhibernateLoggerClass = ConfigurationManager.AppSettings[nhibernateLogger];
            }
            return nhibernateLoggerClass;
        }

That ends returning `null` because both `AppDomain.CurrentDomain.BaseDirectory` and `AppDomain.CurrentDomain.RelativeSearchPath` are `null` probably. So after a day of research im stuck with this issue. Is there any possible workaround?

Thanks in advance.

check out how these guys are using nHibernate: http://www.cjrgaming.com/photon_mmo_development

Might help.