2011-09-05 38 views
4

我已經創建了一個CompositionContainer,現在不是明確地給出類型,而是想通過使用類型的名稱來獲取導出。如何將typename從typename傳遞給MEF中的GetExports?

下面的代碼工作正常:

var p1Value = p.Container.GetExports<IPlugin, IPluginData>() 
    .First(ip => ip.Metadata.Param.Equals(
     args[1], 
     StringComparison.OrdinalIgnoreCase)) 
    .Value 
    .Execute(args.Skip(1).ToArray()); 
Console.WriteLine(p1Value); 

但我想達到同樣的事情,如果我有一個包含「IPlugin」和「IPluginData」兩個字符串變量。有沒有辦法通過名稱傳遞類型?

回答

4

警告:這不是使用MEF的正常方式。但是,既然你問了......你可以使用overload of GetExports,它接受ImportDefinition

要發現您必須爲給定類型使用哪個合同名稱,您可以致電AttributedModelServices.GetContractName(typeof(IPlugin))。通常它只是完整的類型名稱。

確切的元數據類型並不重要 - 所有重要的是在其上聲明的元數據屬性。您可以在下面的requiredMetadata字典中描述這些內容。

var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); 
var container = new CompositionContainer(catalog); 

string contractName = "SomeNamespace.IPlugin"; 
var requiredMetadata = new Dictionary<string, Type>(); 
requiredMetadata["Meta1"] = typeof(string); 
requiredMetadata["Meta2"] = typeof(int); 

var importDefinition = new ContractBasedImportDefinition(
    contractName, 
    null, 
    requiredMetadata, 
    ImportCardinality.ZeroOrMore, 
    false, 
    true, 
    CreationPolicy.Any); 

var exports = container.GetExports(importDefinition); 
Console.WriteLine(exports.Count()); 
Console.ReadKey(); 
+0

嗨Wim,這是工作,但正如你所說的它不是正常的使用MEF的方式,你能否舉一個例子說明什麼是正常和好方法?我正在做的是創建DirectoryCatalog,因爲我將所有插件複製到項目的bin文件夾中,現在我想按名稱和元數據使用類型並使用它。請您建議我有什麼好方法來實現這一目標? – RAJ

+0

@RAJ:你爲什麼需要按類型名稱來做這件事?這是我擔心的部分。通常情況下,你有一個消費者使用'[Import]'或[ImportMany]'屬性,並且這個消費者需要某種類型的'IPlugin'。如果您事先沒有這種類型,那麼您將如何使用導入的對象? –

+0

Wim,原因是我創建了一些在控制檯應用程序中組成的組件,所以我可以將命令傳遞給我的實用程序。控制檯應用程序將能夠接受由應用程序中的不同合同提供的不同命令(一種是IPlugin,另一種可能由IImportFile,IExportFile等)。這就是它的全部理念。 – RAJ

相關問題