几天前,我看到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 反编译器中查看 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 互操作的上下文中,我立刻设想它被用作“穷人的编译时依赖注入”。
所要做的就是摆脱接口名称上的传统“I”前缀(与COM互操作一样)。
然后只需要改变 CoClass 属性来交换实现,进行模拟等。
我看到的两个缺点是必须重新编译(这基本上将测试方案限制在开发时间),以及接口和实现部署到不同程序集时可能出现的循环依赖问题。
有人尝试过这种技术吗?其他缺点?其他用途?