简体   繁体   English

Activator.CreateInstance(Type) 作为接口返回 null

[英]Activator.CreateInstance(Type) as Interface returns null

I have this as the main class of my dll:我把这个作为我的 dll 的主要 class:

namespace PTEmu
{

    public class DatabaseProtocol : IDatabaseProtocol
    {
      (constructors and methods)
    }
 }

This code I use to Load the DLL and create an instance of the class此代码用于加载 DLL 并创建 class 的实例

var assembly = Assembly.LoadFrom("database\\" + file);
var t = assembly.GetType("PTEmu.DatabaseProtocol");
var protocol = Activator.CreateInstance(t) as IDatabaseProtocol;

Assembly.LoadFrom, assembly.GetType and Activator.CreateInstance itself, doesn't throw any errors. Assembly.LoadFrom, assembly.GetTypeActivator.CreateInstance本身不会引发任何错误。

I can't see what is wrong, sice I took this piece of code from another project that worked fine with it.我看不出有什么问题,因为我从另一个可以正常工作的项目中获取这段代码。

If I remove as IDatabaseProtocol , it returns an object, but not an object like the interface I want, so I can call the methods easily...如果我删除as IDatabaseProtocol IDatabaseProtocol ,它返回一个 object,但不是我想要的接口那样的 object,所以我可以轻松调用这些方法...

This is a problem of type identity . 这是类型标识的问题。 The identity of a type in .NET is not just the namespace name and type name. 在.NET中使用类型的身份只是命名空间名称和类型名称。 It also includes the assembly from which it came. 它还包括它来自的程序集。 So the mistake here is that you had two distinct interface types. 所以这里的错误是您有两种不同的接口类型。 One that came from your main assembly, another that came from the plugin assembly. 一个来自您的主程序集,另一个来自插件程序集。 Adding the source code file with Add Link isn't good enough, it matters which assembly the type got compiled into. 用“添加链接”添加源代码文件还不够好,这关系到将类型编译到哪个程序集中。 Or in other words, the source code file plays no role at all in the type identity. 换句话说,源代码文件在类型标识中根本不起作用。

Notable perhaps is that this rule was changed in .NET 4. The identity of a type can be the solely determined by the value of the [Guid] attribute applied to the type. 可能值得注意的是,该规则已在.NET 4中更改。类型的标识可以仅由应用于该类型的[Guid]属性的值确定。 This enabled the "Embed Interop Types" feature in the properties of an assembly reference. 这将在程序集引用的属性中启用“嵌入互操作类型”功能。 Also known as the No PIA feature. 也称为No PIA功能。 It is however only valid on COM interface types. 但是,它仅在COM接口类型上有效。 It put an end to having to install massive PIAs when you write code that automates Office apps. 当您编写使Office应用程序自动化的代码时,它不必安装大量的PIA。

You'll however have to do the exact equivalent of a PIA, a third assembly that defines the interface type and is referenced by both projects. 但是,您必须做与PIA完全相同的工作,PIA是定义接口类型并被两个项目都引用的第三个程序集。

I solved my problem by adding a new project named framework that stores the interface. 我通过添加一个存储framework名为framework的新项目解决了我的问题。 Then I referenced it in my two other projects. 然后在其他两个项目中引用了它。

Don't bother and don't waste your time!不要打扰,不要浪费你的时间!

  1. Create a new DIFFERENT class library for interfaces为接口创建一个新的 DIFFERENT class 库
  2. Create an interface in this new library在这个新库中创建一个界面
  3. implement the interface in your class (other project)在您的 class(其他项目)中实现接口
  4. try to re-run尝试重新运行
  5. TAADAAAM!!! TAADAAAM!

.net need this interface to be in OTHER class library and not the same one!! .net 需要此接口在其他 class 库中而不是同一个库中!!

I had almost similar issue.我有几乎类似的问题。 But in my case the interface was already in a different shared class library.但在我的例子中,接口已经在不同的共享 class 库中。 Solution was to set the "Copy Local" property for the shared reference project to "No".解决方案是将共享参考项目的“复制本地”属性设置为“否”。

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM