手动加载nhibernate.dll程序集

时间:2016-03-15 22:16:12

标签: c# .net nhibernate dll

我有一个带有简单插件系统的小型asp.net webapi应用程序。 所有插件都位于" / bin / debug / plugins /"夹。 我在应用程序启动时加载插件并从autofac容器中的插件注册组件。

但我有一个nhibernate插件的问题,它包含我的存储库,映射等。插件加载后也加载了nhibernate.dll(使用ProcessExporer检查它:http://postimg.org/image/mm4w56vln/)。然后我尝试创建ISessionFactory ...并接收下一个错误

Could not load file or assembly 'NHibernate, Version=4.0.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4' or one of its dependencies. The system cannot find the file specified.":"NHibernate, Version=4.0.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4

我的插件加载程序:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using Jarres.Plugin.Exceptions;

namespace Jarres.Plugin
{
    public class PluginLoader : IPluginLoader
    {
        private readonly List<Assembly> _cache = new List<Assembly>();

        public IDictionary<PluginInfo, IPlugin> Load(IEnumerable<PluginInfo> plugins)
        {
            if (plugins == null)
            {
                throw new ArgumentNullException("plugins");
            }

            InitializeCache();

            AppDomain.CurrentDomain.AssemblyResolve += ResolveModuleAssembly;
            var result = plugins.ToDictionary(x => x, GetPlugin);
            AppDomain.CurrentDomain.AssemblyResolve -= ResolveModuleAssembly;

            return result;
        }

        private IPlugin GetPlugin(PluginInfo plugin)
        {
            var path    = plugin.Path;
            var name    = plugin.Name;
            var version = plugin.Version;

            var fileversion = FileVersionInfo.GetVersionInfo(path).ProductVersion;
            if (version != fileversion)
            {
                throw new PluginVersionException(name, version, fileversion);
            }

            var types = LoadAssembly(path).GetExportedTypes().Where(x => typeof (IPlugin).IsAssignableFrom(x) && !x.IsAbstract).ToArray();
            if (types.Length == 0)
            {
                throw new PluginNotFoundException(name, path);
            }
            if (types.Length > 1)
            {
                throw new MultiplePluginsException(name, path);
            }

            return (IPlugin)Activator.CreateInstance(types[0]);             
        }

        private Assembly LoadAssembly(string path)
        {
            var assembly = GetFromCacheByPath(path);

            if (assembly == null)
            {
                assembly = Assembly.LoadFile(path);
                AddToCache(assembly);
                LoadAssemblyReferences(assembly);
            }

            return assembly;
        }

        private void LoadAssemblyReferences(Assembly assembly)
        {
            foreach (var reference in assembly.GetReferencedAssemblies())
            {
                var directory = Path.GetDirectoryName(assembly.Location);

                if (directory != null)
                {
                    var path = Path.Combine(directory, reference.Name + ".dll");
                    if (File.Exists(path))
                    {
                        LoadAssembly(path);
                    }
                }
            }
        }

        private Assembly ResolveModuleAssembly(object sender, ResolveEventArgs args)
        {
            return GetFromCacheByName(args.Name);
        }


        #region cache

        private void InitializeCache()
        {
            _cache.AddRange(AppDomain.CurrentDomain.GetAssemblies());
            foreach (var assembly in Assembly.GetExecutingAssembly().GetReferencedAssemblies())
            {
                _cache.Add(Assembly.Load(assembly));
            }
        }

        private void AddToCache(Assembly assembly)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException("assembly");
            }

            _cache.Add(assembly);
        }

        private Assembly GetFromCacheByPath(string path)
        {
            var name = Path.GetFileNameWithoutExtension(path);
            return _cache.FirstOrDefault(x => x.GetName().Name == Path.GetFileName(name));
        }

        private Assembly GetFromCacheByName(string name)
        {
            return _cache.FirstOrDefault(a => a.FullName.StartsWith(name));
        }

        #endregion

    }
}

只有将nhibernate.dll复制到/ bin / debug /文件夹时才能创建ISessionFactory。但我想将此dll存储在插件文件夹中。 例如,我对实体框架插件没有任何问题。

为什么我在加载nhibernate.dll时无法创建ISessionFactory?

2 个答案:

答案 0 :(得分:0)

可能你缺乏依赖性。使用fusion logger. (This is a link to a SO question on how to use it.)

发现它

答案 1 :(得分:0)

解决。 所有引用都正确加载,但此引用不在/ bin / {Debug,Release} /文件夹中。 所以,我将目标文件夹的路径添加到我的app.config中。