assembly.GetTypes()和getexporttedtypes()不返回所有公共对象

本文关键字:公共对象 返回 getexporttedtypes GetTypes assembly | 更新日期: 2023-09-27 18:17:11

我试图得到一些插件的东西在asp.net mvc工作。我的插件DLL有一个控制器和一个描述符/模块类。

控制器签名如下所示:

[Export("SomeController", typeof(System.Web.Mvc.IController))]
[PartCreationPolicy(System.ComponentModel.Composition.CreationPolicy.NonShared)]
public class SomeController : System.Web.Mvc.Controller
{ }

和模块描述符类具有以下签名:

[Export("SomeModule", typeof(Plugins.IModule))]
[PartCreationPolicy(System.ComponentModel.Composition.CreationPolicy.NonShared)]
public class SomeModule : Plugins.IModule
{ }

现在这个"插件"程序集是动态加载的,没有问题。当我使用GetTypes()和getexporttedtypes()方法时,问题出现了:

private void GetModuleEntry(Assembly a) {
   IModule module = null;
   Type type = a.GetTypes()
                .Where(t => t.GetInterface(typeof(IModule).Name) != null).FirstOrDefault();
   if (type != null) { do something }
   else { throw exception; }
}

因此,问题在于给定上面的类签名,GetTypes()和getexporttedtypes()(不使用Where子句)都只返回SomeController类。任何方法都不会列出SomeModule类!在使用Where子句执行下一条语句之前,我检查了我设置的断点并在直接命令窗口上调用GetTypes()和getexporttedtypes()。

为什么呢?为什么我的模块类被遗漏,即使它是一个公共类,也有导出的属性?

assembly.GetTypes()和getexporttedtypes()不返回所有公共对象

你的代码为我工作;我在一个空的WinForms应用程序外壳中尝试的代码如下:

如果我不得不猜测你的问题,我相信它与以下两个有关:

FirstOrDefault:是否有可能您查看内部的程序集有两个实现IModule的类,并且第一个发现的不是SomeModule而是不同的东西?这样你的代码就永远找不到SomeModule

在GetModuleEntry中对IModule的引用:是否有可能在您定义GetModuleEntry的项目中引用包含接口IModule的程序集的新版本或不同版本?除非GetModuleEntry方法引用了包含包含SomeModule的程序集所引用的IModule定义的确切DLL,否则您可能会遇到问题。

我认为后者最有可能,或者至少会给你指明解决问题的正确方向。

下面是工作良好的测试代码,因为只有一个类实现了IMyInterface(所以FirstOrDefault是OK的),所有的类/接口都在同一个模块中:

public interface IMyInterface
{ }
public class bar
{ }
[Export("SomeController", typeof(bar))]
[PartCreationPolicy(System.ComponentModel.Composition.CreationPolicy.NonShared)]
public class foo : bar
{ }
[Export("SomeModule", typeof(IMyInterface))]
[PartCreationPolicy(System.ComponentModel.Composition.CreationPolicy.NonShared)]
public class ifoo : IMyInterface
{ }
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
        Type type = a.GetTypes()
            .Where(t => t.GetInterface(typeof(IMyInterface).Name) != null).FirstOrDefault();
        if (type != null) // type is of Type ifoo
        {
            Console.WriteLine("Success!"); 
        }
    }
}