【问题标题】:"Newing up" Interfaces“更新”界面
【发布时间】:2009-08-20 02:56:57
【问题描述】:

几天前,我看到 CoClassAttribute 以一种我以前从未想象过的方式使用。


[ComImport, CoClass(typeof(Foo)), Guid("787C1303-AE31-47a2-8E89-07C7257B1C43")]
interface IFoo {
    void Bar();
}

class Foo : IFoo {
    public void Bar() {
        Console.WriteLine("Oh retado!");
    }
}

被用作:


class CoClassDemo {
    public static void Show() {
        var a = new IFoo();
        a.Bar();
    }
}

这应该不会让我感到惊讶,因为 COM Interop 从 .NET Framework 的早期开始就是这样做的。在 .NET Reflector 中挖掘 COM 互操作代码时,我根本没有过多关注。


method public hidebysig static void Show() cil managed
{
    .maxstack 1
    .locals init (
        [0] class ConsoleApplication1.IFoo a)
    L_0000: nop 
    L_0001: newobj instance void ConsoleApplication1.Foo::.ctor()
    L_0006: stloc.0 
    L_0007: ldloc.0 
    L_0008: callvirt instance void ConsoleApplication1.IFoo::Bar()
    L_000d: nop 
    L_000e: ret 
}

发生的事情是,在 COM Interop 的上下文之外,我立即设想它被用作穷人的编译时依赖注入

所有要做的就是去掉接口名称上传统的“I”前缀(COM Interop 也是如此)。

然后就是更改 CoClass 属性以将一个实现换成另一个实现、模拟等。

我预先看到的两个缺点是必须重新编译(这几乎限制了测试场景的开发时间)以及当接口和实现部署到不同的程序集时围绕循环依赖的最终问题。

有人玩过这种技术吗? 还有什么缺点吗? 其他用途?

【问题讨论】:

  • 高中时上过商店课吗? “为正确的工作使用正确的工具。”使用专为 COM 互操作设计的工具来做完全不同的事情是个坏主意。这使得下一个必须维护它的人无法理解你的代码。请记住,下一个人很可能是你,多年后你已经完全忘记了自己为什么会做这件疯狂的事。

标签: c# dependency-injection mocking


【解决方案1】:

我知道这周末至少有两篇博文 - mineAyende's

对于大多数代码,这应该仅仅被视为一种好奇心。我认为将它用于依赖注入是一种滥用,因为已建立的 IoC/DI 框架可以做得更好,而且很简单。

特别是,这种方法依赖于 §17.5 的逃生舱口,这是 Microsoft 对规范的特定扩展...您希望您的代码在 Mono 上运行吗?我没试过,但是没有具体的原因应该在gmcs/dmcs下编译。

Jon 有一个 better example 在具体代码中使用它 - 故意模拟 COM,但那是为了玩弄 .NET 4.0 / dynamic。再次;这不适用于大多数“常规”代码。

所以不; 不要这样做 - 这只是为了好玩。

【讨论】:

  • 就目前而言,我也将其视为一种好奇心。我仍在脑海中的后台线程中处理这些信息,我仍然想知道是否还有其他“创造性”使用这种技术。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-17
  • 2014-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多