【问题标题】:Instantiate class using reflection使用反射实例化类
【发布时间】:2012-10-01 20:49:39
【问题描述】:

我有不同的类库,每个类库都实现了一个接口IImportCharacter。在我的主应用程序中,用户选择了一个 DLL,应用程序需要检查库是否实现了接口,然后在实现它的库中实例化类。我正在尝试使用反射来做到这一点,但我不断得到:

无法将“CustomCharacter.Ogre”类型的对象转换为类型 'MainGame.IImportCharacter'。

Assembly assembly = assemblyPath;
foreach (Type type in assembly.GetTypes())
{
    IImportCharacter instance = null;
    if (type.GetInterface("IImportCharacter") != null)
    {
        //exception thrown at this line
        instance = (IImportCharacter)Activator.CreateInstance(type);
    }
}

我已将相同的IImportCharacter 文件复制到主项目中,否则编译器会抱怨它不知道IImportCharacter 是什么。我认为这可能会导致问题,因为它与动态加载的不同。我该如何解决这个问题?

【问题讨论】:

  • 您是否确保 IImportCharacter 可由 AssemblyResolver 解析,即存在于 AppDomain、Path、GAC 等中?顺便说一句 - 如果您使用的是 .net 4 及更高版本,请使用 MEF。你会想知道 MS 没有早点介绍这个
  • 您不能创建接口的实例。你需要有一个类来创建一个实例。
  • 尝试将 typeof(IImportCharacter).FullName 而不是“IImportCharacter”传递给 .GetInterface() 方法。
  • @Krishna 这是可以解决的。我会看看 MEF,但它可能有点矫枉过正(虽然还没有看到)@Joel 问题是我不知道类的名称,因此无法将 CreateInstance 转换为正确的类型.有没有办法得到这个? @DJ 恐怕在这些链接中看不到任何对这里有帮助的东西。 @Dmitry 没有抛出错误,但从未到达该行,所以它只是返回 NULL。

标签: c# reflection dll interface .net-assembly


【解决方案1】:

是的,我认为您要转换的接口是具有相同名称的不同类型。为什么不将 IImportCharacter 移动到一个共享程序集,您可以从您的代码和您正在加载的程序集中引用它,因为它是您的界面?

否则,请尝试在动态加载的类型上使用 Convert.ChangeType() 和动态加载的接口。

【讨论】:

  • 我尝试了转换方法,但有一个异常说Object must implement IConvertible.我会尝试共享组装方法,但如果可能的话,我宁愿避免使用额外的组装。
  • 如果您希望能够在本地使用该界面,我认为这会更干净。否则,您也只能通过反射调用接口,这会比较麻烦。无论如何,将接口和实现分开是一个很好的做法。这意味着您可以直接针对接口方法编写代码,但仍然可以在运行时通过反射交换实现。
  • 谢谢,我将为此使用共享程序集。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多