2014-05-13 13 views
6

phép nói rằng tôi có một giao diện IFileLoader và thuộc tính FileTypeAttributeloại tải MEF mà thực hiện giao diện và kết hợp các thuộc tính

Và tôi thực hiện IFileLoader trong JPEGLoader với [Kiểu Tệp ("jpg")]

tôi có thể sử dụng MEF để nạp lớp (JPEGLoader) mà thực hiện IFileLoader và phù hợp với .jpg như phần mở rộng tập tin để tôi có thể thực hiện các phương pháp sau đây:

public void IFileLoader GetLoader(string filename); 

này có thể được thực hiện với MEF, hay tôi nên dính vào này:

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); 

Hoặc ở trên biến thành ILookup ít nhất, hoặc có thể một cái gì đó khác mà tôi đã không xem xét?

Tôi muốn có thể triển khai IFileLoader trong các hội đồng khác nhau của dự án hoặc thậm chí trong các hội đồng plugin.

Trả lời

2

Có thể tải trình tải tệp bạn cần bằng cách sử dụng MEF và đính kèm Metadata vào các phần được xuất.

Tạo giao diện siêu dữ liệu và thuộc tính.

public interface IFileTypeMetadata 
{ 
    string FileExtension { get; } 
} 

Giao diện có thể chứa nhiều thuộc tính bạn cần. Đối với vấn đề cụ thể này, nó chỉ chứa một thuộc tính FileExtension. Điều quan trọng là tài sản chỉ có getter. MEF được thiết kế để không cho phép thay đổi siêu dữ liệu khi chạy. Sau đó tạo ra các thuộc tính chứa siêu dữ liệu:

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

Lớp FileTypeAttribute thực hiện giao diện IFileTypeMetadata, và bạn có thể thêm một setter đến FileExtension tài sản. Nó là cần thiết cho việc thực hiện các FileLoader lớp học, và MEF sẽ không phàn nàn bởi vì chúng ta sẽ truy cập vào siêu dữ liệu thông qua giao diện IFileTypeMetadata có chứa tài sản mà chỉ có getters

Tạo giao diện mà lớp tập loader thực hiện và các lớp tập loader.

public interface IFileLoader 
{ 
    string LoadFile(); 
} 

Giao diện chỉ chứa một phương pháp để đơn giản. Và đây là ví dụ về hai loại tập tin dummy loader khác nhau:

[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"; 
    } 
} 

Cả lớp thực hiện các giao diện IFileLoader và được xuất khẩu như IFileLoader phần, nhưng họ có siêu dữ liệu khác nhau, thông qua các thuộc tính FileType.

Tạo container thành phần

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

truy cập xuất khẩu phụ tùng

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" 
Các vấn đề liên quan