是否可以(ab)使用CoClassAttribute为接口提供默认实现

本文关键字:接口 实现 默认 CoClassAttribute 使用 ab 是否 | 更新日期: 2023-09-27 18:14:05

我最近发现可以通过用CoClassAttribute装饰接口来指定默认实现来"新建"c#中的接口。

[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-interop,但是我想知道这是否是一种将接口与泛型类库中的默认实现相关联的合理方式。

我有两个问题:

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

  2. 即使这将顺利工作,是否有其他原因(从api设计的角度来说)来避免这种情况?

是否可以(ab)使用CoClassAttribute为接口提供默认实现

你不应该这样做的关键原因是你在一个不需要它的对象的实例上启动了COM生命周期管理,. net现在必须做一些COM互操作,包括安全堆栈遍历、公寓线程检查和地址/发布等。

相反,我会考虑使用依赖注入(控制反转模式)和公共服务定位器模式。我将专注于理解构造函数注入,因为它是依赖管理的首选模式。

这是我在我的库中所做的。假设我想编写一个日志服务(虚构的示例)。我将有两个核心组件:

MyStuff.Logging。契约——这里是我声明ILogger接口的地方MyStuff。日志——这里是我编写不同的日志实现的地方,我可能有像FileLogger, DatabaseLogger等。

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

使用智能注释:

    /// <summary>
    /// Explain here all about interface
    /// </summary>

而不是修改属性,因为它可能在使用您的类的其他人的半反射实现中适得其反。属性是为使用反射的工具使用的,智能感知是为文档使用的。

当然,一些旧的工具在读取你的///注释时会有问题,但是它们也不能读取你的属性。