【问题标题】:Is it possible to assign an interface to an object at runtime?是否可以在运行时将接口分配给对象?
【发布时间】:2011-03-24 16:57:19
【问题描述】:

在回想了我收到的previous question about modeling my code to maximize code re-use 的所有出色答案后,我开始想知道是否可以在运行时而不是在编码时将接口分配给对象。

my previous question 中的一段简化代码为例:

public class OutboxManager
{
    private IVendorMessenger _VendorMessenger;

    //This is the default constructor, forcing the consumer to provide
    //the implementation of IVendorMessenger.
    public OutboxManager(IVendorMessenger messenger)
    {
         _VendorMessenger = messenger;
    }

    public void DistributeOutboxMessages()
    {
        VendorMessenger.SendMessageToVendor()
                      _OutboxMgrDataProvider.MarkMessageAsProcessed(om)
    }

}

目前,如果有人想使用这个类,他们必须编写一个实现IVendorMessenger的类,并在初始化时作为参数提供:

 var MyOutboxManger = new OutboxManager(new MyVendorMessenger())

如果不是对接口参数进行硬编码,而是在运行时分配它会怎样?这样,我可以为实现IVendorMessenger 的类编译一个dll,将其放入OutboxManagerExecutable 存在的同一文件夹中,它会在运行时连接所有内容。我想,使用这个逻辑,我可以想出一种方法将IVendorMessenger多个 实现放在同一个文件夹中,并将可执行文件设计为足够智能以遍历所有适当的 dll 并相应地使用它们.

这种功能在 .NET 4 中是否可行?

【问题讨论】:

  • 你是说你想要一个不实现 IVendorMessenger 的类,并在运行时将该接口插入到它上面来表示它实现了吗?
  • @Lasse 不,我想插入的任何类都假定IVendorMessenger

标签: .net design-patterns oop interface


【解决方案1】:

查看Managed Extensibility Framework (MEF)。正如您所描述的那样,它可以自动组合您的应用程序的依赖项。它附带 .NET 4.0。

【讨论】:

  • 我以前听说过MEF,但我不确定它是否可以用来解决这类问题。我想知道它的用途是什么。
  • @Ben:我链接的网站上有很多例子。
【解决方案2】:

这是一个非常常见的反射用例。 .NET API 为您提供了您需要的部分:

  1. 查找目录中的所有 .dll:Directory.GetFiles()
  2. 在运行时加载这些程序集:Assembly.LoadFile()
  3. 遍历每个程序集中的类型:Assembly.GetTypes()
  4. 对于每种类型,看看它是否实现了你的接口:Type.IsAssignableFrom()
  5. 如果是,获取并调用其构造函数来创建一个:Type.GetConstructor()

之后,您将获得一个 Object,您可以将其转换为 IVendorMessenger 并传递它。

【讨论】:

    【解决方案3】:

    您是否考虑使用 MEF?它允许您创建许多模块的应用程序构建。

    你可以看到here

    【讨论】:

    • 哎呀.. 看起来我迟到了 30 秒 ;)
    【解决方案4】:

    编辑:我刚刚意识到我误解了这个问题。这个问题确实不是,事实上,似乎是关于在运行时将接口分配给对象,而是关于后期绑定类型名称。

    我会将答案保留为社区 Wiki,以防其他人有同样的误解。


    这通常称为接口注入,只要 CLI 和 JVM 存在,它们就一直在愿望清单上。

    尤其是那些为并非为 CLI 或 JVM 原生设计的编程语言编写实现的人,如 JRuby、XRuby、Ruby.NET、IronRuby、IronPython、Jython、Rhino、IronJS 等他们的愿望清单,因为这意味着他们不再需要维护一个并行的类型层次结构并在两者之间来回编组对象。

    然而,它们似乎不会很快出现,甚至根本不会出现,尽管至少有一个适用于 JVM 的稻草人规范以及随附的达芬奇机器的部分原型实现。

    【讨论】:

    • örg 感谢您的回复。我想我实际上是在寻找后期绑定风格的解决方案,但我不知道如何措辞。但是,关于您的答案,Interface InjectionDependency Injection 有何不同?
    【解决方案5】:

    您应该可以在 .Net 2.0/3.0 中使用Generics 做到这一点(在课堂上)。

    您也可以使用Reflection to load a dll during runtime

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-09
      • 1970-01-01
      • 1970-01-01
      • 2013-05-08
      • 1970-01-01
      相关资源
      最近更新 更多