手动加载 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存储在插件文件夹中。例如,我对实体框架插件没有任何问题。

为什么我不能在 nhibernat .dll 加载时创建 ISessionFactory?

可能你缺少依赖性。用融合记录仪发现它。(这是有关如何使用它的 SO 问题的链接。

已解决。所有引用都正确加载,但此引用不在/bin/{调试、发布}/文件夹中。因此,我将目标文件夹的路径添加到我的app.config中。

最新更新