是否确定(AB)使用CoCl​​assAttribute提供接口的默认实现? [英] Is it ok to (ab)use CoClassAttribute to provide a default implementation for an interface?

查看:216
本文介绍了是否确定(AB)使用CoCl​​assAttribute提供接口的默认实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近发现,它可能新达在C#通过装饰用的 CoClassAttribute 指定一个默认的实现。

  [ComImport中GUID(579A4F68-4E51-479A-A7AA-A4DDC4031F3F),伴生类(typeof运算(FooImpl))]
公共接口IFoo的
{
    无效酒吧();
}

公共类FooImpl:IFoo的
{
    公共无效酒吧(){}
}

...

//构造一个FooImpl
IFoo的富=新的IFoo();
 

我知道这个功能的存在主要是为了支持COM的互操作,但我想知道,这将是一个合理的方式与通用类库的默认实现的接口联系起来。

我有两个问题:

  1. 有没有用这样任何陷阱?我不是COM-互操作方面的专家,我不知道这是否会对波苏斯任何负面影响。我没有运行任何重大考验,但在IL我的例子似乎确定对 FooImpl newobj 指令>而不是调用 Type.GetTypeFromCLSID Activator.CreateInstance )。

  2. 即使这会工作的顺利开展,有其他原因(比如从一个API设计的角度看),以避免这种情况?

解决方案

你不应该这样做的关键原因是,你开始COM生命周期管理上,这并不需要一个对象的实例。 .NET现在必须做一些COM互操作,其中包括一个安全堆栈散步,公寓线程检查和的AddRef /释放的东西。

相反,我会考虑寻找依赖注入(控制模式反转)和通用Service Locator模式。我想重点了解构造函数注入,因为它是preferred模式的依赖管理。

这是我做我的图书馆。比方说,我想写一个日志服务(人为的例子)。我想有两个核心组件:

MyStuff.Logging.Contracts - 这里就是我会宣布ILogger接口 MyStuff.Logging - 这里就是我会写不同的日志实现我可能有这样FileLogger,DatabaseLogger等

然后在我的应用程序,我会使用任何Ninject或Unity(DI容器),以ILogger的默认实现关联。

I recently discovered that it's possible to "new up" an interface in C# by decorating the interface with the CoClassAttribute to specify a default implementation.

[ComImport, Guid("579A4F68-4E51-479A-A7AA-A4DDC4031F3F"), CoClass(typeof(FooImpl))]
public interface IFoo
{
    void Bar();
}

public class FooImpl : IFoo
{
    public void Bar() { }
}

...

// Constructs a FooImpl
IFoo foo = new IFoo();

I'm aware that this feature exists primarily to support COM-interop, but I was wondering if this would be a reasonable way to associate interfaces with default implementations in generic class-libraries.

I have two questions:

  1. Are there any gotchas with doing this? I'm not an expert on COM-interop and I don't know if this will have any negative impact on POCOs. I haven't run any major tests, but the the IL for my example seems ok (a normal newobj instruction on FooImpl rather than calls to Type.GetTypeFromCLSID and Activator.CreateInstance).

  2. Even if this would work smoothly, are there other reasons (say from an API-design perspective) to avoid this?

解决方案

The key reason you shouldn't do this is that you are starting the COM lifecycle management on an instance of an object that doesn't need it. .NET will now have to do some COM interop that includes a security stack walk, apartment threading checks, and addref/release stuff.

Instead, I would consider looking at dependency injection (inversion of control pattern) and the Common Service Locator Pattern. I would focus on understanding constructor injection as it is the preferred pattern for dependency management.

Here's what I do in my libraries. Let's say I want to write a logging service (contrived example). I would have two core components:

MyStuff.Logging.Contracts - Here is where I would declare the ILogger interface MyStuff.Logging - Here is where I would write the different logging implementations I might have like FileLogger, DatabaseLogger, etc.

Then in my application I would use either Ninject or Unity (DI containers) to associate ILogger with the default implementation.

这篇关于是否确定(AB)使用CoCl​​assAttribute提供接口的默认实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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