c# – 如果存在某个属性,则加载程序集
好的,这是交易:
我想将用户定义的程序集加载到我的AppDomain中,但是如果指定的程序集符合某些要求,我只想这样做.就我而言,除了其他要求之外,它必须具有我们可以调用MandatoryAssemblyAttribute的程序集级别属性. 据我所知,我可以走两条路: >将程序集加载到我当前的AppDomain中,并检查属性是否存在.容易但不方便,因为即使它没有MandatoryAssemblyAttribute,我仍然坚持加载的程序集.不好. 说起来容易做起来难.在网上搜索,我找到了几个关于如何解决这个问题的例子,包括在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的情况下迭代加载的程序集?我究竟做错了什么? 非常感谢任何建议. 解决方法
这不太准确.您需要知道的是类型名称是某个程序集,不一定是您要检查的程序集.您应该在程序集中创建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; } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |