为插件类提供一个人类可读的名称

时间:2013-03-11 12:32:26

标签: c# plugins interface

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

我想让插件的开发人员清楚地了解他们需要做些什么来使他们的插件工作。

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

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

    void Consume(DataRowSet rows);

    ...
}

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

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

2 个答案:

答案 0 :(得分: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;
    }
}

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

答案 1 :(得分:3)

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

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