2014-05-13 4 views
6

Können sagen, ich habe eine Schnittstelle IFileLoader und das Attribut FileTypeAttributeMEF Lasttypen, die Schnittstelle und Spiel implementieren Attribute

Und ich implementieren IFileLoader in JPEGLoader mit [Filetype („jpg“)]

Kann ich MEF die Klasse (JPEGLoader) zu laden, die IFileLoader implementiert und passt als Dateierweiterung .jpg so dass ich die folgende Methode implementieren:

public void IFileLoader GetLoader(string filename); 

kann dies mit MEF getan werden, oder sollte ich an dieser haften bleiben:

var allTypes = assemblies.SelectMany(a => a.GetTypes()); 
var classes = allTypes.Where(t => t.IsClass && ! t.IsAbstract); 
var fileLoaders = classes.where(t => typeof(IFileLoader).IsAssignableFrom(t)); 
var forType = fileLoaders.Where(t => t.GetAtributeValue<FileTypeAttribute,string>(t => t.FileType, string.Empty) == fileType); 
var loaderInstances = fileLoaders.Select(t => Activator.CreateInstance(t) as IFileLoader); 

Oder wurde das oben genannte in ILookup umgewandelt, oder vielleicht etwas anderes, das ich nicht berücksichtigt habe?

Ich würde gerne in der Lage sein, den IFileLoader in verschiedenen Assemblys des Projekts oder sogar in Plugins zu implementieren.

Antwort

2

Es ist möglich, den benötigten Dateilader unter Verwendung von MEF und attachnig Metadata zu den exportierten Teilen zu bekommen.

Metadatenschnittstelle und -attribut erstellen.

public interface IFileTypeMetadata 
{ 
    string FileExtension { get; } 
} 

Die Schnittstelle kann so viele Eigenschaften enthalten, wie Sie benötigen. Für dieses spezielle Problem enthält es nur eine Eigenschaft FileExtension. Es ist wichtig, dass die Immobilie nur getter hat. MEF ist so konzipiert, dass Metadaten zur Laufzeit nicht geändert werden können. Erstellen Sie dann das Attribut, das die Metadaten enthält:

public class FileTypeAttribute : Attribute, IFileTypeMetadata  
{   
    public string FileExtension { get; set; } 
} 

Die FileTypeAttribute Klasse IFileTypeMetadata Schnittstelle implementiert, und Sie können eine setter zum FileExtension Eigenschaft hinzuzufügen. Es ist für die Umsetzung der FileLoader Klassen benötigt, und MEF nicht beschweren, weil wir die Metadaten über die IFileTypeMetadata Schnittstelle, die Eigenschaften enthalten, zugreifen, die nur getters

die Schnittstelle erstellen, die Klassen-Datei loader implementieren und die Datei loader-Klassen.

public interface IFileLoader 
{ 
    string LoadFile(); 
} 

Die Schnittstelle enthält nur eine Methode aus Gründen der Einfachheit. Und hier ist beispielsweise aus zwei verschiedenen Dummy-Klassen-Datei loader:

[Export(typeof(IFileLoader))] 
[FileType(FileExtension = ".jpg")] 
public class JpgFileLoader : IFileLoader 
{ 
    public string LoadFile() 
    { 
     return "JPG"; 
    } 
} 

[Export(typeof(IFileLoader))] 
[FileType(FileExtension = ".png")] 
public class PngFileLoader : IFileLoader 
{ 
    public string LoadFile() 
    { 
     return "PNG"; 
    } 
} 

Beide Klassen implementieren die IFileLoader Schnittstelle und werden als IFileLoader Teile exportiert, aber sie haben unterschiedliche Metadaten über das FileType Attribut.

den Behälter Zusammensetzung erstellen

var catalog = new DirectoryCatalog("path to directory where dll's are located"); 
var compositionContainer = new CompositionContainer(catalog); 
compositionContainer.ComposeParts(); 

Zugang exportierten Teile

var fileLoaders = compositionContainer.GetExports<IFileLoader, IFileTypeMetadata>(); 

var jpgFileLoader = fileLoaders.FirstOrDefault(x => x.Metadata.FileExtension == ".jpg"); 

if (jpgFileLoader != null) 
    Console.WriteLine(jpgFileLoader.Value.LoadFile()); //should print "JPG" 

var pngFileLoader = fileLoaders.FirstOrDefault(x => x.Metadata.FileExtension == ".png"); 

if (pngFileLoader != null) 
    Console.WriteLine(pngFileLoader.Value.LoadFile()); //should print "PNG" 
Verwandte Themen