How do you use ExportFactory<T>

余生长醉 提交于 2019-12-18 05:14:53

问题


I am new to MEF and experimenting with ExportFactory. Can I use ExportFactory to create a list based on user insertion of objects? A sample would be something similar to what is shown below. I am probably not understanding the use of ExportFactory because during runtime I get an error shown below during composition.

1) No valid exports were found that match the constraint '((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"))))', invalid exports may have been rejected.

 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()
    {
    }
}

回答1:


The problem appears to be that you expect to import a single ExportFactory<IFoo>, but you have exported two different IFoo implementations. In your example, MEF wouldn't be able to decide between both implementations.

You probably want to import multiple factories including metadata like this:

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

where IFooMeta would be declared like this:

public interface IFooMeta
{
    string CompType { get; }
}

and then you could implement CreateComponent like this:

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


来源:https://stackoverflow.com/questions/11488297/how-do-you-use-exportfactoryt

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!