给一个插件类一个人类可读的名字

本文关键字:一个 插件 人类 | 更新日期: 2023-09-27 18:03:14

我正在为我的应用程序创建一个插件系统,我想为插件暴露一个人类可读的名称。应用程序将显示一个可用插件列表,在这个列表中需要有可用的名称。

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

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

public interface IDataConsumer : IDisposable
{
    string ConsumerName { get; }
    void Consume(DataRowSet rows);
    ...
}
有没有办法强制插件类提供元数据而不创建每个类型的实例?

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

给一个插件类一个人类可读的名字

不可以,属性不能作为接口契约的一部分。但是我们强烈推荐他们。

我过去做过的事被做成一个属性,比如:

[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;
    }
}

如果文档中有这样的要求,那么要求插件开发人员使用该属性应该不会太过分。

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

然而,基于属性的解决方案有什么问题?当然,你不能为了避免编译失败而强制使用该属性,但是你可以在加载插件(甚至更早)时这样做。