【问题标题】:Cannot cast Class to Interface from dynamically loaded DLL无法将类从动态加载的 DLL 转换为接口
【发布时间】:2015-03-20 17:27:12
【问题描述】:

我有以下课程

namespace WAM.Modules.AlertScanner
{
  public class Module : IModule
  {
    private Page _main;
    private Page _options;
    private String _name;
    private ViewModels.AlertScanner _scanner;

    public Page MainPage()
    {
        return _main;
    }

    public Page OptionsPage()
    {
        return _options;
    }

    public string Name()
    {
        return _name;
    }

    public Module()
    {
        _name = "Alert Scanner";
        _scanner = new ViewModels.AlertScanner();
        _main = new Views.Main(_scanner.Main_Data);
        _options = new Views.Options(_scanner.Options_Data);
    }
  }
}

还有一个界面

namespace WAM.Shared.Interfaces
{
  interface IModule
  {
    Page MainPage();

    Page OptionsPage();

    String Name();
  }
}

我希望能够在运行时加载一个 dll,其中包含一个名为“Module”的类,其接口为“IModule”,并将其转换为所述接口。

我在 SO 上找到了以下代码并对其进行了一些更改以获得以下代码

string fullpath = Path.GetFullPath(path);
Assembly ass = Assembly.LoadFrom(fullpath);
Type t = ass.GetType("WAM.Modules.AlertScanner.Module");
var o = Activator.CreateInstance(t);
IModule module = (IModule)o;
Console.WriteLine("Module : {0}", module.Name());

但是,VS 总是在铸造部分崩溃

{“无法将'WAM.Modules.AlertScanner.Module'类型的对象转换为'WAM.Shared.Interfaces.IModule'类型。”}

更新:

目前我只有一个 dll:WAM.Modules.AlertScanner.dll

也只有一个exe:WAM.Desktop.exe

解决方案中有3个项目:

  • WAM.Desktop(Windows 应用程序)
  • WAM.Shared(共享项目)
  • WAM.AlertScanner(类库)

这里列出的类太多了,但在此上下文中使用的类:

  • 模块 (WAM.Modules.AlertScanner)
  • IModule (WAM.Shared)
  • ManagerModules (WAM.Shared)

ManagerModules 应该在运行时加载具有继承 IModule 的名为 Module 的类的 DLL。 WAM.Shared 在 WAM.Desktop(使用管理器的那个)和 WAM.Modules.AlertScanner(用于继承)中被引用。

更新 2:

问题似乎是我的代码生成了2个版本的接口。

有没有办法让它只保留一个版本的界面?

【问题讨论】:

  • 您加载了两个不同版本的界面。你需要避免这种情况。
  • 你能解释一下你在哪里看到的吗?还有,我该如何避免呢?
  • 你能贴出 DLL 和 EXE 的名称 + 哪个 DLL/EXE 有哪些类/接口吗?
  • 右键单击并单击 AlertScanner 中 IModule 上的“转到定义”,然后右键单击并单击 IModule module = (IModule)o;IModule 上的“转到定义”到同一个程序集中的同一个文件?你得到的错误通常是当我最后一个问题的答案是“不,它需要我到两个不同的程序集”时得到的错误(即使两个程序集在硬盘驱动器上使用相同的文件,因为你使用了“添加现有- >Link”当您将文件添加到程序集的项目时)。
  • 睡觉后,消除过程中的疲劳,我明白你的意思,我认为你是对的。我已更新问题以反映新信息。

标签: c# dll dllimport


【解决方案1】:

由于我没有得到关于我的问题的任何明确答案并且我设法纠正了问题,我发布我的解决方案以防其他人遇到同样的问题:

  • 正如其他人所说,我在每个程序集中都有一个版本的接口,这是导致错误的原因。
  • 这些多个版本的原因是我在共享项目中添加了接口。共享项目有助于集中代码,但是在编译时,每个程序集都会生成自己的代码,这导致了我所处的情况。
  • 解决方案相当简单:将接口移动到另一个程序集中(我将它移动到类库中)并使用该接口在程序集中添加对该程序集的引用。

【讨论】:

    【解决方案2】:

    WAM.Modules.AlertScanner.Module 实现WAM.Modules.AlertScanner.IModule。您正在尝试投射到 WAM.Shared.Interfaces.IModule。认为WAM.Modules.AlertScanner.IModuleWAM.Shared.Interfaces.IModule 看起来一样,具有相同的签名,它们是不同的,因为它们位于不同的命名空间中。您需要将适配器从WAM.Modules.AlertScanner.IModule 写入WAM.Shared.Interfaces.IModule

    【讨论】:

    • 等等,那是我不明白的。我没有 WAM.Modules.AlertScanner.IModule 类。
    • 我用 CodDom 生成了适配器类,将其编译成程序集。当我尝试获取适配器的实例时,我在当前域 assabmlies 中认为它出现异常“无法加载”WAM.Modules.AlertScanner,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”。如果将此组件引用到项目中,它可以工作。我正在尝试解决这个问题。
    • 对不起,我很难理解您的评论。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-24
    • 2010-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多