可以(ab)使用 CoClassAttribute 为接口提供默认实现吗? [英] Is it ok to (ab)use CoClassAttribute to provide a default implementation for an interface?

查看:30
本文介绍了可以(ab)使用 CoClassAttribute 为接口提供默认实现吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近发现可以"通过使用 "nofollow">CoClassAttribute 指定默认实现.

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();

我知道此功能的存在主要是为了支持 COM 互操作,但我想知道这是否是将接口与通用类库中的默认实现相关联的合理方式.

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.

我有两个问题:

  1. 这样做有什么问题吗?我不是 COM 互操作方面的专家,我不知道这是否会对 POCO 产生任何负面影响.我还没有运行任何主要测试,但我的示例的 IL 似乎没问题(FooImpl 上的正常 newobj 指令,而不是调用 Type.GetTypeFromCLSIDActivator.CreateInstance).

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

即使这会顺利进行,是否还有其他原因(例如从 API 设计的角度)可以避免这种情况?

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

推荐答案

您不应该这样做的关键原因是您正在一个不需要它的对象实例上启动 COM 生命周期管理..NET 现在必须执行一些 COM 互操作,包括安全堆栈遍历、单元线程检查和 addref/release 内容.

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 - 这里是我声明 ILogger 接口的地方MyStuff.Logging - 在这里,我将编写不同的日志记录实现,例如 FileLogger、DatabaseLogger 等.

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.

然后在我的应用程序中,我将使用 Ninject 或 Unity(DI 容器)将 ILogger 与默认实现相关联.

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

这篇关于可以(ab)使用 CoClassAttribute 为接口提供默认实现吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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