【问题标题】:NHibernate is unable to resolve classes in a dynamically loaded assembly loaded from a subdirectoryNHibernate 无法解析从子目录加载的动态加载程序集中的类
【发布时间】:2018-06-26 13:10:05
【问题描述】:

//格式化不正确。

使用nhibernate和.net core编写的nopcommerce插件,每个插件都包含自己的实体目录,但是当NHibernate配置失败时

var cfg = new Configuration();
cfg.Configure(CommonHelper.MapPath("~/App_Data/db/defauls.config"));
// error here
cfg.AddAssembly("plugins assembly name");

FileNotFoundException:无法加载文件或程序集“插件程序集名称”或其依赖项之一。系统找不到指定的文件。

System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, string codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, ref StackCrawlMark stackMark, IntPtr pPrivHostBinder, bool throwOnFileNotFound, bool forIntrospection, bool suppressSecurityChecks) MappingException:持久类“插件程序集名称.Entities.class 名称,插件程序集名称找不到

NHibernate.Cfg.XmlHbmBinding.Binder.ClassForFullNameChecked(string fullName, string errorMessage) MappingException:无法编译映射文档:插件程序集名称.Entities.class name.hbm.xml

NHibernate.Cfg.Configuration.LogAndThrow(Exception exception)

【问题讨论】:

  • 如果插件中的 cfg 或非嵌入式资源 hbm.xml 文件没有发生错误,我认为问题不在于 NHibernate,它与我加载程序集的方式有关,但不知道如何解决
  • 请将程序集名称与您的插件命名空间一起传递。如果您的插件命名空间是 Nop.Plugin.Misc.Name 并且 DLL 程序集名称是 MyExample.Core.DLL 则您必须传递 Nop.Plugin.Misc.Name.MyExample.Core 这将适用于在插件中添加程序集。
  • 命名空间 Plugin.Shop.Entities,在 Plugin.Shop.Entities 中组装 Plugin.Shop 我有类 Amounts.cs 和文件 Amounts.hbm.xml
  • 比传入 Plugin.Shop.Entities.Plugin.Shop 程序集名称
  • 您可以在插件根文件夹中添加 DLL 并从中提供参考

标签: nhibernate .net-core nhibernate-mapping


【解决方案1】:

假设 Plugin.Shop.dll 位于插件 Plugin.Shop.Entities 文件夹的根文件夹中。 从属性中选择内容类型作为嵌入式资源 并给出此 DLL 的引用并从属性中将其设置为 False 以复制出文件夹。

这是 EmbeddedAssembly.cs 文件

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Security.Cryptography;

namespace Plugin.Shop.Entities
{
    public class EmbeddedAssembly
    {
        // Version 1.0

        static Dictionary<string, Assembly> dic = null;

        public static void Load(string embeddedResource, string fileName)
        {
            if (dic == null)
                dic = new Dictionary<string, Assembly>();

            byte[] ba = null;
            Assembly asm = null;
            Assembly curAsm = Assembly.GetExecutingAssembly();

            using (Stream stm = curAsm.GetManifestResourceStream(embeddedResource))
            {
                // Either the file is not existed or it is not mark as embedded resource
                if (stm == null)
                    throw new Exception(embeddedResource + " is not found in Embedded Resources.");

                // Get byte[] from the file from embedded resource
                ba = new byte[(int)stm.Length];
                stm.Read(ba, 0, (int)stm.Length);
                try
                {
                    asm = Assembly.Load(ba);

                    // Add the assembly/dll into dictionary
                    dic.Add(asm.FullName, asm);
                    return;
                }
                catch
                {
                    // Purposely do nothing
                    // Unmanaged dll or assembly cannot be loaded directly from byte[]
                    // Let the process fall through for next part
                }
            }

            bool fileOk = false;
            string tempFile = "";

            using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
            {
                string fileHash = BitConverter.ToString(sha1.ComputeHash(ba)).Replace("-", string.Empty); ;

                tempFile = Path.GetTempPath() + fileName;

                if (File.Exists(tempFile))
                {
                    byte[] bb = File.ReadAllBytes(tempFile);
                    string fileHash2 = BitConverter.ToString(sha1.ComputeHash(bb)).Replace("-", string.Empty);

                    if (fileHash == fileHash2)
                    {
                        fileOk = true;
                    }
                    else
                    {
                        fileOk = false;
                    }
                }
                else
                {
                    fileOk = false;
                }
            }

            if (!fileOk)
            {
                System.IO.File.WriteAllBytes(tempFile, ba);
            }

            asm = Assembly.LoadFile(tempFile);

            dic.Add(asm.FullName, asm);
        }

        public static Assembly Get(string assemblyFullName)
        {
            if (dic == null || dic.Count == 0)
                return null;

            if (dic.ContainsKey(assemblyFullName))
                return dic[assemblyFullName];

            return null;
        }
    }
}

这是依赖寄存器文件

using Autofac;
using Autofac.Core;
using Nop.Core.Configuration;
using Nop.Core.Data;
using Nop.Core.Infrastructure;
using Nop.Core.Infrastructure.DependencyManagement;
using Nop.Data;
using Nop.Web.Framework.Mvc;
using System;
using System.Reflection;

namespace Plugin.Shop.Entities.Infrastructure
{
    /// <summary>
    /// Dependency registrar
    /// </summary>
    public class DependencyRegistrar : IDependencyRegistrar
    {       
        public virtual void Register(ContainerBuilder builder, ITypeFinder typeFinder, NopConfig config)
        {
            builder.RegisterType<NameService>().As<INameService>().InstancePerLifetimeScope();

            string codeDll = "Plugin.Shop.Entities.Plugin.Shop.dll";
            EmbeddedAssembly.Load(codeDll, "Plugin.Shop.dll");

            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
        }

        private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            return EmbeddedAssembly.Get(args.Name);
        }

        public int Order
        {
            get { return 1; }
        }
    }
}

【讨论】:

  • @JoyceK - 希望这是工作并将此帖子标记为答案,以便对社区有所帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-08
  • 1970-01-01
  • 2011-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多