3

私は MEF が初めてで、ExportFactory を試しています。ExportFactory を使用して、ユーザーによるオブジェクトの挿入に基づいてリストを作成できますか? サンプルは、以下に示すようなものになります。実行時に構成中に以下に示すエラーが発生するため、おそらく ExportFactory の使用を理解していません。

1) 制約に一致する有効なエクスポートが見つかりませんでした '((exportDefinition.ContractName == "System.ComponentModel.Composition.ExportFactory(CommonLibrary.IFoo)") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "System. ComponentModel.Composition.ExportFactory(CommonLibrary.IFoo)".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))'、無効なエクスポートが拒否された可能性があります。

 class Program
{
    static void Main(string[] args)
    {
        Test mytest = new Test();
    }
}

public class Test : IPartImportsSatisfiedNotification
{
    [Import]
    private ExportFactory<IFoo> FooFactory { get; set; }

    public Test()
    {
        CompositionInitializer.SatisfyImports(this);
        CreateComponent("Amp");
        CreateComponent("Passive");
    }

    public void OnImportsSatisfied()
    {
        int i = 0;
    }

    public void CreateComponent(string name)
    {
        var componentExport = FooFactory.CreateExport();
        var comp = componentExport.Value;
    }
}

public interface IFoo
{
    double Name { get; set; }
}

[ExportMetadata("CompType", "Foo1")]
[Export(typeof(IFoo))]
[PartCreationPolicy(System.ComponentModel.Composition.CreationPolicy.NonShared)]
public class Foo1 : IFoo
{
    public double Name { get; set; }
    public Foo1()
    {

    }
}

[ExportMetadata("CompType", "Foo2")]
[Export(typeof(IFoo))]
[PartCreationPolicy(System.ComponentModel.Composition.CreationPolicy.NonShared)]
public class Foo2 : IFoo
{
    public double Name { get; set; }
    public Foo2()
    {
    }
}
4

1 に答える 1

11

問題は、単一の をインポートすることを期待しているようですが、2 つの異なる実装ExportFactory<IFoo>をエクスポートしたことです。IFooあなたの例では、MEF は両方の実装を決定できません。

おそらく、次のようなメタデータを含む複数のファクトリをインポートする必要があります。

[ImportMany]
private IEnumerable<ExportFactory<IFoo,IFooMeta>> FooFactories 
{ 
    get;
    set;
}

whereIFooMetaは次のように宣言されます。

public interface IFooMeta
{
    string CompType { get; }
}

そして、次CreateComponentのように実装できます。

public IFoo CreateComponent(string name, string compType)
{
    var matchingFactory = FooFactories.FirstOrDefault(
        x => x.Metadata.CompType == compType);
    if (matchingFactory == null)
    {
        throw new ArgumentException(
            string.Format("'{0}' is not a known compType", compType),
            "compType");
    }
    else
    {
        IFoo foo = matchingFactory.CreateExport().Value;
        foo.Name = name;
        return foo;
    }
}
于 2012-07-17T15:08:33.167 に答える