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

通常、私は「ありません」と言います。これは、インスタンスを作成しなくても情報を型から引き出すことができるメカニズムが2つあるためstaticです。メンバーと属性です。これらのメカニズムとインターフェースの間に重複はないため、指定されたすべての要件を同時に満たすことはできません。

しかし、属性ベースのソリューションの何が問題になっていますか?確かに、失敗したコンパイルの苦痛に属性の存在を強制することはできませんがプラグインをロードするとき(またはそれ以前)にそれを行うことができます。

于 2013-03-11T12:35:59.960 に答える