c# – 如果存在某个属性,则加载程序集

c# – 如果存在某个属性,则加载程序集,第1张

概述好的,这是交易: 我想将用户定义的程序加载到我的AppDomain中,但是如果指定的程序集符合某些要求,我只想这样做.就我而言,除了其他要求之外,它必须具有我们可以调用MandatoryAssemblyAttribute的程序集级别属性. 据我所知,我可以走两条路: >将程序集加载到我当前的AppDomain中,并检查属性是否存在.容易但不方便,因为即使它没有MandatoryAssemblyA 好的,这是交易:

我想将用户定义的程序集加载到我的AppDomain中,但是如果指定的程序集符合某些要求,我只想这样做.就我而言,除了其他要求之外,它必须具有我们可以调用MandatoryAssemblyAttribute的程序集级别属性.

据我所知,我可以走两条路:

>将程序集加载到我当前的AppDomain中,并检查属性是否存在.容易但不方便,因为即使它没有MandatoryAssemblyAttribute,我仍然坚持加载的程序集.不好.
>我可以创建一个新的AppDomain并从那里加载程序集并检查我的旧MandatoryAddemblyAttribute是否存在.如果是,则转储创建的AppDomain并继续将Assembly加载到我的CurrentAppDomain中,如果没有,只需转储新的AppDomain,告诉用户,让他再试一次.

说起来容易做起来难.在网上搜索,我找到了几个关于如何解决这个问题的例子,包括在SO:Loading DLLs into a separate AppDomain中发布的上一个问题

我在这个解决方案中看到的问题是,您实际上必须知道要加载的程序集中的类型(全名).这不是我喜欢的解决方案.重点是尝试插入符合某些要求的任意程序集,并通过属性发现要使用的类型.事先不知道大会将具有哪些类型.当然,我可以要求任何以这种方式使用的程序集都应该实现一些虚拟类,以便为CreateInstanceFromAndUnwrap提供一个“入口点”.我宁愿不.

另外,如果我继续沿着这条线做点什么:

using (var frm = new OpenfileDialog()){    frm.DefaultExt = "dll";    frm.Title = "Select dll...";    frm.Filter = "Model files (*.dll)|*.dll";    answer = frm.ShowDialog(this);     if (answer == DialogResult.OK)     {          domain = AppDomain.CreateDomain("Model",new EvIDence(AppDomain.CurrentDomain.EvIDence));          try          {              domain.CreateInstanceFrom(frm.filename,"Dummynamespace.DummyObject");                    modelisValID = true;          }          catch (TypeLoadException)          {              ...          }          finally          {              if (domain != null)                   AppDomain.Unload(domain);          }     }}

这样可以正常工作,但如果那时我会继续执行以下 *** 作:

foreach (var ass in domain.GetAssemblIEs()) //Do not fret,I would run this before unloading the AppDomain    Console.Writeline(ass.Fullname);

我得到一个fileNotFoundException.为什么?

我可以采取的另一条道路就是这一条道路:How load DLL in separate AppDomain 但我也没有任何运气.每当我选择一些随机的.NET程序集时,我都会得到一个fileNotFoundException,除此之外它还会失败,因为我需要知道程序集的名称(不是文件名)才能加载它,这与我的要求不符.

有没有其他方法可以做到这一点除非MEF(我不是针对.NET 3.5)?或者我是否坚持创建一些虚拟对象以通过CreateInstanceFromAndUnwrap加载程序集?如果是这样,为什么我不能在没有得到fileNotFoundException的情况下迭代加载的程序集?我究竟做错了什么?

非常感谢任何建议.

解决方法

The problem I see with this solution is that you actually have to kNow
a type (full name) in the Assembly

这不太准确.您需要知道的是类型名称是某个程序集,不一定是您要检查的程序集.您应该在程序集中创建MarshalByRef类,然后使用CreateInstanceAndUnwrap从您自己的程序集(而不是您要检查的程序集)创建它的实例.然后该类将执行加载(因为它存在于新的appdomain中)并检查并将布尔结果返回到原始appdomain.

这里有一些代码可以帮助你.这些类在你自己的程序集中(不是你要检查的那个):

第一个类用于创建检查AppDomain并创建MarshalByRefObject类的实例(参见底部):

using System;using System.Security.Policy;internal static class AttributeValIDationUtility{   internal static bool ValIDateAssembly(string pathToAssembly)   {      AppDomain appDomain = null;      try      {         appDomain = AppDomain.CreateDomain("ExaminationAppDomain",new EvIDence(AppDomain.CurrentDomain.EvIDence));         AttributeValIDationMbro attributeValIDationMbro = appDomain.CreateInstanceAndUnwrap(                              typeof(AttributeValIDationMbro).Assembly.Fullname,typeof(AttributeValIDationMbro).Fullname) as AttributeValIDationMbro;         return attributeValIDationMbro.ValIDateAssembly(pathToAssembly);      }      finally      {         if (appDomain != null)         {            AppDomain.Unload(appDomain);         }      }   }}

这是MarshalByRefObject,它实际上将存在于新的AppDomain中,并将对程序集进行实际检查:

using System;using System.Reflection;public class AttributeValIDationMbro : MarshalByRefObject{   public overrIDe object InitializelifetimeService()   {      // infinite lifetime      return null;   }   public bool ValIDateAssembly(string pathToAssembly)   {      Assembly assemblyToexamine = Assembly.LoadFrom(pathToAssembly);      bool hasAttribute = false;      // Todo: examine the assemblyToexamine to see if it has the attribute      return hasAttribute;   }}
总结

以上是内存溢出为你收集整理的c# – 如果存在某个属性,则加载程序集全部内容,希望文章能够帮你解决c# – 如果存在某个属性,则加载程序集所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1248138.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存