问题描述
几天前,我看到 CoClassAttribute 以一种我以前从未想象过的方式使用.
A couple of days ago, I saw the CoClassAttribute being used in a way I haven't imagined before.
[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 互操作代码时,我根本没有过多关注.
That should have not surprised me since COM Interop does exactly that since the early days of the .NET Framework. I simply haven’t paid that much attention when digging through COM Interop code in .NET Reflector.
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 的上下文之外,我立即设想它被用作穷人的编译时依赖注入.
What happened is that out of the context of COM Interop, I immediately I envisioned this being used as a poor man’s compile time dependency injection.
所有要做的就是去掉接口名称上传统的I"前缀(COM Interop 也是如此).
All there is to do is get rid of the conventional "I" prefix on the interface's name (as does COM Interop).
然后就是更改 CoClass 属性以将一个实现换成另一个实现、模拟等.
Then it would be a matter of changing the CoClass attribute to swap an implementation for another, mocking, etc.
我预先看到的两个缺点是必须重新编译(这几乎限制了测试场景的开发时间)以及当接口和实现部署到不同的程序集时围绕循环依赖的最终问题.
Two drawbacks I see upfront are having to recompile (which pretty much limits testing scenarios to development time) and eventual problems surrounding circular dependencies when interfaces and implementations are deployed to different assemblies.
有人玩过这种技术吗?还有什么缺点吗?其他用途?
Has anybody played with this technique? Any other drawbacks? Other uses?
推荐答案
我知道这周末至少有两篇博文 - 我的 和 Ayende 的.
I know this got at least two blog posts on the weekend - mine and Ayende's.
对于大多数代码,这应该仅仅被视为一种好奇心.我认为将它用于依赖注入是一种滥用,因为已建立的 IoC/DI 框架可以做得更好,而且很简单.
For most code, this should be treated merely as a curiosity. I think it would be an abuse to use this for dependency injection, when established IoC/DI frameworks can do the job so much better, and so simply.
特别是,这种方法依赖于 §17.5 的逃生舱口,这是微软特定于规范的扩展...您希望您的代码在 Mono 上运行吗?我没试过,但没有具体的理由应该在gmcs/dmcs下编译.
In particular, this approach relies on the escape hatch of §17.5, a Microsoft-specific extension to the spec... do you want your code to run on Mono? I haven't tried it, but there is no specific reason that it should compile under gmcs / dmcs.
Jon 有一个 更好在具体代码中使用它的示例 - 故意模拟 COM,但那是为了玩弄 .NET 4.0/dynamic
.再次;这不适用于大多数常规"代码.
Jon had a better example of using it in concrete code - for deliberately mocking COM, but that was for toying with .NET 4.0 / dynamic
. Again; this wouldn't apply to most "regular" code.
所以不;不要这样做 - 这只是为了好玩.
So no; don't do it - it is just a fun aside.
这篇关于“更新"接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!