1

新しいプロジェクトでMEFを使用しようとしていますが、インポートを機能させるのに問題がありますが、その理由は説明できません。私はMSDNや他の場所でサンプルをフォローしていますが、それらは私のために機能していません。これは、.NET4プロジェクトでMEF4.0を使用しています。

私は簡単な契約を定義しました:

public interface ICommand
{
    int Execute(string[] args);
}

いくつかの部分を実装し、いくつかのメタデータを追加しました。

[Export(typeof(ICommand))]
[ExportMetadata("Name", "init")]
public class InitCommand : ICommand { ... }

[Export(typeof(ICommand))]
[ExportMetadata("Category", "service")]
[ExportMetadata("Name", "start")]
public class StartServiceCommand : ICommand { ... }

次のメタデータインターフェイスを定義しました。

public interface ICommandMetadata
{
    [DefaultValue(null)]
    string Category { get; }

    string Name { get; }
}

メインプログラムでは、カタログベースのエクスポートプロバイダーを作成してから、メインプログラムオブジェクトを作成しようとしています。

internal class Program
{
    [ImportMany]
    private IEnumerabe<Lazy<ICommand, ICommandMetadata>> commands;

    private static int Main(string[] args)
    {
        var assembly = Assembly.GetExecutingAssembly();
        var assemblyExportProvider = new CatalogExportProvider(new AssemblyCatalog(assembly));
        var compositionContainer = new CompositionContainer(assemblyExportProvider);
        assemblyExportProvider.SourceProvider = compositionContainer;
        var batch = new CompositionBatch();
        batch.AddPart(this);
        compositionContainer.Compose(batch);

        return 0;            
    }
}

上記のコードを実行すると、これは期待どおりに機能し、両方の部分が解決されます。さらに一歩進んでカスタムエクスポート属性を作成すると、コードが機能しなくなります。これが私のカスタムメタデータ属性と更新された部分です:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
[MetadataAttribute]
public sealed class CommandAttribute : ExportAttribute
{
    public CommandAttribute() : base(typeof(ICommand))
    {
    }

    [DefaultValue(null)]
    public string Category { get; set; }

    public string Name { get; set; }
}

[Command(Name = "init")]
public class InitCommand : ICommand { ... }

[Command(Category = "service", Name = "start")]
public class StartServiceCommand : ICommand { ... }

カスタムエクスポート属性を適用することにより、プログラム内のコマンドコレクションは空の配列になります。これをもう少し試してみたところ、メタデータインターフェイスのプロパティを文字列の配列に変更すると、インポートが再び機能することがわかりました。

public interface ICommandMetadata
{
    [DefaultValue(null)]
    string[] Category { get; }

    string[] Name { get; }
}

私が何か間違ったことをしているのか誰か教えてもらえますか?メタデータインターフェイスで配列を使用する場合にのみこれが機能するのはなぜですか?プロパティに配列を使用せずにこれを機能させる方法はありますか?

よろしくお願いします。

4

0 に答える 0