可以導出元數據類,這裏有一個例子:
public interface ILogger
{
void Log(string message);
}
[Export(typeof(ILogger)), ExportMetadata("Name", "Console")]
public class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine(message);
}
}
[Export(typeof(ILogger)), ExportMetadata("Name", "Debug")]
public class DebugLogger : ILogger
{
public void Log(string message)
{
Debug.Print(message);
}
}
鑑於合同,這些示例實現,我們可以導入了類型爲Lazy<T, TMetadata>
由此我們可以定義元數據合同:
public interface INamedMetadata
{
string Name { get; }
}
您不必擔心創建元數據的實現,因爲MEF會將任何ExportMetadata
屬性值作爲具體實現TMetadata
(在我們的示例中爲INamedMetadata
。通過上述,我可以創建下面的例子:
public class Logger
{
[ImportMany]
public IEnumerable<Lazy<ILogger, INamedMetadata>> Loggers { get; set; }
public void Log(string name, string message)
{
var logger = GetLogger(name);
if (logger == null)
throw new ArgumentException("No logger exists with name = " + name);
logger.Log(message);
}
private ILogger GetLogger(string name)
{
return Loggers
.Where(l => l.Metadata.Name.Equals(name))
.Select(l => l.Value)
.FirstOrDefault();
}
}
在該示例類,我進口很多情況下,爲Lazy<ILogger, INamedMetadata>
實例。使用Lazy<T,TMetadata>
允許我們在訪問該值之前訪問元數據。在上面的示例中,我使用name
參數來選擇要使用的適當記錄器。
如果在導入時實例化該類是不對的,可以使用ExportFactory<T,TMetadata>
,它允許您按需添加類型的實例。 (ExportFactory
被包括在.NET 4.0中的Silverlight版本,但格倫座沒有拋出的源代碼on codeplex桌面/網絡使用。
我希望幫助。
由於喬希,我試圖用合同名稱並且它解決了我的問題,但是如果我在出口部件中使用合同名稱,則不能使用ImportMany。有沒有辦法將ImportMany與Import特定部件一起使用? – Ray 2011-01-06 04:35:40
並非如此。總之,無論如何您都不能輕易地將Import和ImportMany結合使用。因爲如果你有一個導入並且有多個導出,你將會遇到同樣的異常,然而你可能會在構造函數中導入ImportMany,然後根據其他邏輯選擇一個導入。 – Josh 2011-01-06 05:18:41