【问题标题】:Finding classes in a DLL that inherit from classes in an unavailable assembly在 DLL 中查找从不可用程序集中的类继承的类
【发布时间】:2013-04-17 03:22:59
【问题描述】:

我正在开发一种工具,可以将插件加载到我们在办公室使用的商业软件中。可以通过创建一个 .NET 程序集来开发该软件的插件,该程序集的类继承自软件 API 中的类。

所以我的软件需要检查 DLL 以确定它们是否包含按名称从 API 插件类继承的类。但是,我不希望我的应用程序依赖于 API 本身。它不需要实例化或执行这些类中的任何一个,只需确定从 API 插件类继承的类的全名。

我可以使用以下方法加载 dll 程序集:

Assembly.LoadFrom(dllFileName)

然而,当我尝试在加载的程序集上调用 GetTypes() 时。我收到一个 ReflectionTypeLoadException,其中包含许多 LoaderExceptions,抱怨找不到 API 文件。

我也尝试过使用ReflectionOnlyLoadFrom(),但它抛出了同样的异常。

还有其他方法可以获取此信息吗?同样,我不需要执行任何代码,最终我希望我的工具可以在根本没有安装 API 或软件的计算机上工作。我只需要知道完整的类名。

【问题讨论】:

  • 一个疯狂的猜测,你的dllFileName 是否依赖于其他dll's。如果是,这些 dll 的搜索路径是否相同?
  • 是的,这就是重点。感兴趣的 DLL 依赖于其他程序集(API),但我不希望我的工具依赖于 API 程序集。我没有尝试执行任何代码,只是确定 DLL 中的哪些类继承自 API 程序集中的特定类

标签: c# .net reflection .net-assembly system.reflection


【解决方案1】:

使用框架的反射 API 无法做到这一点。反射需要访问程序集以加载类型元数据。您可以做的是使用 Mono.Cecil(可在 nuget 上获得)之类的东西来检查 MSIL。下面是一个示例,其中显示了在程序集中具有基类和接口的类型:

using Mono.Cecil;
using Mono.Cecil.Cil;

var assembly = AssemblyDefinition.ReadAssembly("ClassLibrary.dll");
// skip the first type '<Module>' whatever that is.
var types = assembly.MainModule.Types.Skip(1);

foreach (var type in types)
{
    var interfaces = type.Interfaces.Select(i => i.FullName);
    if (interfaces.Any())
    {
         Console.WriteLine("{0} : {1}, {2}", type.FullName, type.BaseType.FullName, string.Join(", ", interfaces));
    }
    else
    {
         Console.WriteLine("{0} : {1}", type.FullName, type.BaseType.FullName);
    }
}

这不会导致程序集或其任何依赖项被加载。当您知道您感兴趣的类直接从外部 API 类继承时,这将很有用。如果有多个继承级别,那么您将不得不做比我上面显示的更多的工作。

【讨论】:

  • 谢谢。我尝试安装 Mono.Ceil,但 type.BaseType.FullName 属性返回“System.Object”,而不是 API 程序集中的类名。
  • @EricAnastas 这很奇怪。我使用类似于您在问题中描述的场景测试了代码,并获得了预期的基本类型。如果你看它 ildasm,它会说什么?
  • 是的,Reflector 和 ildasm 都显示了正确的基本类型。 Ildasm 显示类似“实现 [APIAssembly]Company.Software.Foobar.APIAddInClass”
  • @EricAnastas 如果它说“实现”它听起来像一个界面。我相信 ildasm 对基类说“扩展”。我也编辑了示例以显示界面。
  • 嗯,是的。对不起,我忘了它是一个接口而不是类继承。
【解决方案2】:

无法使用Reflection。如果您只是对查找依赖项感兴趣,可以使用ObjectExplorer 查看DLL 程序集中的类并查看它们的基类型。并寻找不属于同一个程序集的类型。

你可以在这里找到一些有用的信息:
Which program in Visual Studio lets me look into DLLs to see its API?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-19
    • 2019-01-02
    • 1970-01-01
    • 2015-08-31
    • 2010-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多