如何从未(实际)加载的程序集中获取自定义属性

Mar*_*tke 6 c# plugins attributes assemblies

我们都知道可以使用GetCustomAttributes方法查询程序集的属性.我想用它来为我的应用程序识别扩展模块.但是,为了避免加载每个组件,我更喜欢防御方法:

  1. 使用Assembly.ReflectionOnlyLoadFrom获取有关程序集的更多详细信息(有我的ModuleAttribute吗?)

  2. 如果找到ModuleAttribute,我将最终使用Assembly.LoadFrom加载它

不幸的是,似乎没有办法从程序集中获取属性,该程序集被加载到仅反射上下文中:

myAssembly.GetCustomAttributes(typeof(ModuleAttribute), false)
Run Code Online (Sandbox Code Playgroud)

失败的InvalidOperationException("反映通过ReflectionOnlyGetType加载的Type的自定义属性是非法的")和

CustomAttributeData.GetCustomAttributes(myAssembly)
Run Code Online (Sandbox Code Playgroud)

由于未加载相关的程序集而导致ReflectionTypeLoadException失败.

那么如何获得没有的属性

  1. 通过调用Assembly.LoadFrom以无用(可能有害)类型污染我的应用程序域
  2. 需要加载所有引用的程序集
  3. 需要单独的应用程序域(给它一个简短的尝试,闻起来更像PITA)

Ayk*_*lic 5

可以加载具有依赖性的程序集(仅反射)。

AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += (s, e) => Assembly.ReflectionOnlyLoad(e.Name);

假设它们都在同一文件夹中,则可以修复加载时的故障。


Mar*_*tke 4

检查所有答案并进行更多研究后,似乎根本没有办法做我想做的事:在将程序集加载到应用程序域之前检查程序集是否是有效的扩展模块。

要么我必须将应检查的程序集加载到另一个应用程序域中,在那里检查它,当它成功时再次将其加载到我当前的应用程序域中,或者我需要将程序集的元数据存储在程序集本身之外并信任此元数据。由于架构限制,选项一是不可能的,选项二只是转移了问题,但没有解决问题。

最好的替代方案可能是使用托管可扩展性框架,但不幸的是,这在当前设置中并不那么容易。

我最终相信模块目录中没有什么“坏”的东西并加载所有内容(进行一些检查以确保不超过最大文件大小并且尚未加载)。

尽管如此,还是感谢您的想法。