2012-09-10 85 views
1

我有一些需要創建多個實例的部分導入。通過搜索我決定我需要使用ExportFactory類。不幸的是,默認情況下,ExportFactory類在WPF中不可用,但幸運的是Glenn Block有ported the codeMEF - [ImportMany]在WPF中使用ExportFactory <T> - .NET 4.0

原來,在導入時我指定類型:

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

我還創建了一個出口屬性:

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

我出口是這樣的:

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

以上導入工作正常。但是,一旦我將Lazy<T,T>更改爲ExportFactory<T,T>,我在組合過程中開始出現錯誤。

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

我得到的錯誤信息是:

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

我看到的地方(我找不到鏈接現在),在ImportMany屬性指定Type的問題。我想我可以沒有它,所以我從ImportMany刪除類型。使用Lazy<T,T>

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

該進口仍然工作,但一旦我把它改爲ExportFactory<T,T>,我不再進口任何東西。我再也沒有遇到錯誤,但沒有任何東西被導入。

有誰知道如何正確使用ImportManyExportFactory<T,T>的WPF?

更新:

隨着韋斯的關於添加ExportFactoryProvider()技巧中,我得到了ExportFactory<T,T> .NET 4的工作!以下是更新後的合成代碼。

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

我也發現了這個討論在MEF Codeplex site,討論多一點關於這一點。

+0

記住申請讓 - 菲利普·勒孔特的修復在天空驅動器文件中的註釋中提到: 在ExportFactoryInstantiationProvider在行115: 如果(CBID == NULL || cbid.RequiredTypeIdentity.StartsWith(PartCreatorContractPrefix)!) 應是: 如果(CBID == NULL || cbid.RequiredTypeIdentity == NULL || cbid.RequiredTypeIdentity.StartsWith(PartCreatorContractPrefix)!) 因爲RequiredTypeIdentity(cbid.RequiredTypeIdentity)爲空時,不存在必要型(進口按名稱),從而在空字符串上調用StartsWith。 – Sly

回答

1

一般情況下,.NET 4.0 ExportFactory不支持開箱即用。 ExportFactory是容器(或自定義導出提供程序)知道和特別處理的特殊類型,並且基於您收到的錯誤消息,它看起來不像這個容器知道關於ExportFactory的任何特殊內容,因爲它試圖將其轉換爲IMyModule 。

看看Glen的測試是否爲您的容器添加了Microsoft.ComponentModel.Composition.Hosting.ExportFactoryProvider的ExportFactory?

另請注意,如果您有切換到.NET 4.5的選項,那麼開箱即可支持ExportFactory。

+0

我沒有添加'ExportFactoryProvider'。我正在查看示例項目。除了查看這個可能有幫助的示例項目外,是否還有關於'ExportFactory '的任何文檔?在線瀏覽幫助時,我從未看到有關「ExportFactoryProvider」的任何信息。 – burnttoast11

+0

添加'ExportFactoryProvider'解決了問題!謝謝! – burnttoast11