“新建”接口 [英] "Newing up" Interfaces

查看:104
本文介绍了“新建”接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几天前,我看到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 Interop代码时,我根本没有付出太多的注意力。

  
方法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属性以交换实现n另一个,嘲笑等。



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



有没有人玩过这种技术?
任何其他缺点?
其他用途?

解决方案

我知道这个周末至少有两篇博客文章 - 我的 Ayende's



对于大多数代码,这应该仅仅是好奇心。我认为使用这种方式进行依赖注入将是一种滥用行为,当建立IoC / DI框架可以做得更好,而且简单。



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



Jon有一个使用它的更好的例子具体的代码 - 刻意嘲笑COM,但那是为了用.NET 4.0 / 动态来执行。再次;这不适用于大多数常规代码。



所以没有; 不要这样做 - 这只是一个有趣的一面。


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!");
    }
}

being used as:


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

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 
}

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.

All there is to do is get rid of the conventional "I" prefix on the interface's name (as does COM Interop).

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?

解决方案

I know this got at least two blog posts on the weekend - mine and Ayende's.

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.

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 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.

这篇关于“新建”接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆