8

我正在为我的应用程序创建一个插件系统,我希望插件公开一个人类可读的名称。该应用程序将显示可用插件的列表,在此列表中名称需要可用。

我想让插件的开发人员非常清楚他们需要做什么才能使他们的插件工作。

目前我正在使插件类实现一个接口,并且该接口需要一个属性“ConsumerName”来实现。但是,这需要主应用程序为每个插件创建一个实例,以便使用 CunsumerName 属性,只是为了显示列表。

public interface IDataConsumer : IDisposable
{
    string ConsumerName { get; }

    void Consume(DataRowSet rows);

    ...
}

有没有办法强制插件类提供元数据而不创建每种类型的实例?

我的后备计划是在每个类上使用反射和一些属性,但我不认为属性可以强制使用接口。

4

2 回答 2

4

不,属性不能成为接口合同的一部分。但他们可以强烈推荐。

我过去所做的事情是一个属性,例如:

[AttributeUsage(AttributeTargets.Class)]
public class PluginNameAttribute : Attribute {
    public string ConsumerName { get; set; }
}

如果程序员选择用该属性装饰他的类,那就太好了。如果没有,您可以依靠类名本身:

var consumerName = type.Name;
var nameAttribute = type.GetCustomAttributes(typeof(PluginNameAttribute), true)
    .FirstOrDefault() as PluginNameAttribute;
if (nameAttribute != null) {
    var attributeName = nameAttribute.ConsumerName;
    if (!string.IsNullOrEmpty(attributeName)) {
        consumerName = attributeName;
    }
}

如果有文件证明他们应该这样做,那么要求插件开发人员使用该属性应该不会太多。

于 2013-03-11T12:39:12.830 回答
3

通常我会说“不,没有”。这是因为有两种机制允许从类型中提取信息而不需要创建实例:static成员和属性。由于这些机制和接口之间没有重叠,因此您无法同时满足所有声明的要求。

但是,基于属性的解决方案有什么问题?当然,您不能在编译失败的痛苦中强制属性的存在,但是您可以在加载插件时(甚至更早)这样做。

于 2013-03-11T12:35:59.960 回答