Вы можете экспортировать метаданные с вашим классом, вот пример:
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
включено в версию Silverlight .NET 4.0, но Гленн Блок действительно выбросил исходный код в codeplex для настольных ПК / Web.
Надеюсь, это поможет.*