2

こんばんは、この複雑な作業を手伝っていただけませんか。MEFでモジュールアプリを開発しています。各モジュールには、次のようなメタデータがあります。

    [MetadataAttribute]
        [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
        public abstract class ModuleMetadata : ExportAttribute, IArmModuleMetadata
        {
            private ModuleDescriptor _descriptor;

            public ModuleMetadata(string name, string code, string category, string iconUri)
                : base()
            {
                _descriptor = new ModuleDescriptor(name, code, category, iconUri);               
     }
}

私はこのように使用します:

 [Export(typeof(IArmTaskModule))]
[TaskModuleMetadata("test1", "code",
     @"pack://application:,,,/WpfVisualModule;component/Icons/chart_line_error.png",
     "road_weather_stations",
     TargetItem = TargetItems.ControlComplex)]
class AdvancedChartContract : Burstroy.Arm.Contracts.IArmTaskModule

各モジュールには、 の Dictionary<string, Settings.ParamDescriptor> CreateSettingsBlock()メソッドによって生成された一連のプロパティIArmModuleがあります。Key にはプロパティのコードが含まれ、Value には凝った名前とデフォルト値が含まれます。

私のメインアプリではLazy<T, TMetadata>、このようなモジュールのインポートに使用します

[ImportMany(typeof(IArmTaskModule), AllowRecomposition = true)]
private IEnumerable<Lazy<IArmTaskModule, IArmTaskModuleMetadata>> _taskModules;

メソッドから設定ブロックを受け取るLazy<T, TMetadata>ためのインスタンスを作成するこのアプローチの問題。プロパティ情報をメタデータに追加することでそれを防ぎたいです。new List() で属性コンストラクターを拡張しようとしましたが失敗しました (属性制限)、新しい属性も作成しようとしましたIArmTaskModule

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class ExportedParam : ExportAttribute, IArmModuleProperty
{
    public ExportedParam(string code, string fancyName) 
        : base()
    {
        this.Code = code;
        this.FancyName = fancyName;
        //this.Value = value;
    }

    public string Code { get; private set; }
    public string FancyName { get; private set; }
    public object Value { get; private set; }
}

しかし、それも失敗しています。

[ExportedParam("a", "b")]
[ExportedParam("b", "c")]
[ExportMetadata("fffffuuu", 2)]
class MeteoSummary : IArmVisualModule, 

誰か提案はありますか?

4

1 に答える 1

1

このクラスは、カスタム エクスポート属性のガイドラインModuleMetadataに従っていません。

次のようになります。

    [MetadataAttribute]
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public abstract class ModuleMetadataExportAttribute : ExportAttribute
    {
        public ModuleDescriptor Descriptor { get; private set; }

        public ModuleMetadata(string name, string code, string category, string iconUri)
            : base(typeof(IArmTaskModule))
        {
            Descriptor= new ModuleDescriptor(name, code, category, iconUri);               
        }
     }

そして、次のようなメタデータ インターフェイス:

public interface IArmModuleMetadata
{
    ModuleDescriptor Descriptor { get; }
}

ご了承ください:

  • カスタム エクスポート属性でメタデータ インターフェイスを実装する必要はありません。MEF がこれを処理します。
  • エクスポートされた型を ExportAttribute のコンストラクターに渡す必要があります。
  • カスタム エクスポート属性のすべてのパブリック プロパティをインターフェイスに追加します。

また、カスタム属性を作成するためのガイドラインに準拠するように、カスタム属性クラスの名前を変更しました (現在、このソースを見つけることはできませんが、Cwalina、Abrams による Framework Design Guidelines 2nd edition を確認できます)。ただし、これは必要ありません。

次に、次のようにエクスポートします。

[ModuleMetadataExport(...))] //Add your params here.
[TaskModuleMetadata("test1", "code",
     @"pack://application:,,,/WpfVisualModule;component/Icons/chart_line_error.png",
     "road_weather_stations",
     TargetItem = TargetItems.ControlComplex)]
class AdvancedChartContract : Burstroy.Arm.Contracts.IArmTaskModule

TaskModuleMetadataそれが何かわからないので、私は去りました。MEFとは関係ないと思います。

最後に、インポート部分を変更しないでください。_taskModules次に、シーケンスを反復処理するときに、プロパティをチェックして、現在のモジュールが必要なものであることをValue確認した後でのみ、プロパティにアクセスします。Metadata次に、プロパティにアクセスするValueと、モジュールが作成されます。

于 2012-12-12T16:13:44.413 に答える