几天前,我看到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();
}
}
这应该不会让我感到惊讶,因为自从.NET Framework早期以来,COM Interop正是这样做的。在.NET Reflector中挖掘COM Interop代码时,我根本没有那么多关注。
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属性以将实现交换为另一个,模拟等等。
我预先看到的两个缺点是,当接口和实现部署到不同的程序集时,必须重新编译(这几乎将测试场景限制为开发时间)以及与循环依赖关系相关的最终问题。
有人玩这种技术吗? 还有其他任何缺点吗? 其他用途?
答案 0 :(得分:10)
对于大多数代码来说,这只应被视为好奇心。我认为使用它进行依赖注入是一种滥用,当已建立的IoC / DI框架可以更好地完成工作时,简单。
特别是,这种方法依赖于§17.5的逃逸孵化,这是微软特定的规范扩展......你想让你的代码在Mono上运行吗?我没有尝试过,但没有具体的原因它应该在gmcs / dmcs下编译。
Jon有一个better example在具体代码中使用它 - 故意模仿COM,但那是用于使用.NET 4.0 / dynamic
。再次;这不适用于大多数“常规”代码。
所以没有; 不要这样做 - 这只是一个乐趣。