MEF - [ImportMany] using ExportFactory<T> in WPF - .NET 4.0

佐手、 提交于 2019-12-23 02:36:54

问题


I have some part imports that I need to create multiple instances of. By searching around I decided I needed to use the ExportFactory class. Unfortunately, the ExportFactory class is not available in WPF by default, but luckily Glenn Block has ported the code.

Originally, I was specifying the type when importing:

[ImportMany(typeof(IMyModule))]
public IEnumerable<Lazy<IMyModule, IMyModuleMetadata>> Modules { get; set; }

I also created an export attribute:

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class ExportMyModuleMetadata : ExportAttribute, IMyModuleMetadata
{
    public ExportMyModuleMetadata(string category, string name)
        : base(typeof(IMyModuleData))
    {
        Category = category;
        Name = name;
    }
    public string Category { get; set; }
    public string Name { get; set; }
}

My export looks like this:

[ExportMyModuleMetadata("Standard","Post Processor")]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class Module1 : IMyModuleData

The above import worked fine. But once I changed Lazy<T,T> to ExportFactory<T,T> I started getting an error during composition.

[ImportMany(typeof(IMyModule))]
public IEnumerable<ExportFactory<IMyModule, IMyModuleMetadata>> Modules { get; set; }

The error message I got was:

The export 'Module1 (ContractName="IMyModule")' is not assignable to type
'System.ComponentModel.Composition.ExportFactory`

I saw somewhere (that I can't find the link for right now) that specifying the Type in the ImportMany attribute is the problem. I figured I could do without it so I removed the type from the ImportMany.

[ImportMany()]
public IEnumerable<Lazy<IMyModule, IMyModuleMetadata>> Modules { get; set; }

This import still worked when using Lazy<T,T>, but once I changed it to ExportFactory<T,T>, I no longer import anything. I didn't get an error anymore but nothing gets imported.

Does anyone know how to properly use ImportMany with ExportFactory<T,T> for WPF?

Update:

With Wes's tip about adding an ExportFactoryProvider(), I got the ExportFactory<T,T> working in .NET 4! Below is the updated composition code.

var ep = new ExportFactoryProvider();

//Looks for modules in main assembly and scans folder of DLLs for modules.
var moduleCatalog = new AggregateCatalog(
    new AssemblyCatalog(runningApp),
    new DirectoryCatalog(".", "*.dll"));
var container = new CompositionContainer(moduleCatalog, ep);
ep.SourceProvider = container;
var Modules = new Modules();
container.ComposeParts(Modules);

I also found a discussion on this at MEF Codeplex site that talks a little more about this.


回答1:


In general on .NET 4.0 ExportFactory isn't supported out of the box. ExportFactory is special type that the container (or a custom export provider) knows about and treats specially and based on the error message you have received it doesn't look like this container knows anything special about ExportFactory because it is trying to cast it to IMyModule.

Have a look at Glen's tests for ExportFactory did you add a Microsoft.ComponentModel.Composition.Hosting.ExportFactoryProvider to your container?

Also note that if you have an option to switch to .NET 4.5, ExportFactory is supported out of the box.



来源:https://stackoverflow.com/questions/12359887/mef-importmany-using-exportfactoryt-in-wpf-net-4-0

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