Is it ok to (ab)use CoClassAttribute to provide a default implementation for an interface?

こ雲淡風輕ζ 提交于 2019-12-01 05:03:23

问题


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?


回答1:


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.




回答2:


Use intelisense comments:

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

rather then hacking the attributes, as it might backfire in someone else's semi-reflection implementation that uses your class. Attributes are there to be used by tools that use reflection, intelisense is for documentation.

Granted, some legacy tools will have problems reading your /// comments, but they will not be able to read your attributes either.



来源:https://stackoverflow.com/questions/8094441/is-it-ok-to-abuse-coclassattribute-to-provide-a-default-implementation-for-an

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!