można wyeksportować metadane ze swojej klasy, oto przykład:
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);
}
}
Zważywszy, że umowa i te przykładowe implementacje możemy importować z typów jak Lazy<T, TMetadata>
którym możemy zdefiniować umowę Metadane:
public interface INamedMetadata
{
string Name { get; }
}
Nie musisz martwić się o tworzenie implementacji metadanych, ponieważ MEF wyświetli wartości atrybutów ExportMetadata
jako konkretną implementację TMetadata
, która w naszym przykładzie to INamedMetadata
. Z powyższego można utworzyć następujący przykład:
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();
}
}
W tej klasie próbki, jestem importowania wielu przypadkach jako Lazy<ILogger, INamedMetadata>
przypadkach. Korzystanie z Lazy<T,TMetadata>
pozwala nam uzyskać dostęp do metadanych przed uzyskaniem dostępu do wartości. W powyższym przykładzie używam argumentu name
, aby wybrać odpowiedni rejestrator do użycia.
Jeśli niewłaściwe jest tworzenie klasy podczas importu, można użyć narzędzia ExportFactory<T,TMetadata>
, które pozwala na uruchamianie instancji typów na żądanie. (ExportFactory
jest wliczone w wersji Silverlight z .NET 4.0, ale nie rzucać Glenn Blok kodu źródłowego on codeplex do pulpitu użytkowania/Web.
Mam nadzieję, że pomaga.
Dzięki Josh, starałem się używać nazwy umowne i rozwiązał mój problem, ale nie mogę użyć ImportMany, jeśli używam nazwy kontraktu w Exports Parts.Czy jest jakiś sposób na użycie ImportMany z importowaniem konkretnej części? – Ray
Niezupełnie, ogólnie rzecz biorąc nie można w łatwy sposób łączyć importu z funkcją ImportMany. Przyczyna, jeśli masz import i istnieje więcej niż jeden eksport, trafisz w ten sam wyjątek. Możesz jednak importować dowolnie w konstruktorze, a następnie wybrać jeden z importowanych na podstawie innej logiki. – Josh