2012-09-11 84 views
2

我完全是MEF的新手,想在我目前正在開發的項目中使用它。MEF ImportMany類型參數:優雅的解決方案?

想法:我想寫一個FileLoader<T>這需要T作爲參數類型,我試圖加載,並提供我的哪些文件擴展支持加載到這種類型的數據。類型載入器分散在解決方案中作爲Func<string, T>提供,應由MEF收集到IEnumerable中。然後從元數據收集支持的文件類型。

現在這就是我試圖做到這一點:

[Export(typeof(IFileLoader<>))] 
class FileLoader<TData> : IFileLoader<TData> 
{ 
    static FileLoader() 
    { 
     SimpleIoc.Default.Register(() => { return new FileLoader<Model.CompositeSignal<Model.SignalBase>>(); }); 
    } 

    [ImportMany(typeof(Func<string, TData>))] // Problem here!!! 
    private IEnumerable<Func<string, TData>> Loaders { get; set; } 

    public FileLoader() 
    { 
     //TODO: Compose here 
    } 

    public IEnumerable<FileExtensionFilter> GetSupportedFiletypes() 
    { 
     throw new NotImplementedException(); 
    } 

    public TData LoadFromFile(string filename) 
    { 
     throw new NotImplementedException(); 
    } 
} 

//////////////// Somewhere else in a class ////////////////////////////////////// 

    [Export(typeof(Func<string, CompositeSignal<SignalBase>>))] 
    [SupportedFileType(FileTypeDescription="Signal interpolation file", FileTypeMask="*.interpol.xml")] 
    public CompositeSignal<InterpolatedSignal> InterpolationFileLoader(string filename) 
    { 
     throw new NotImplementedException(); //TODO 
    } 

//////////////////////////////////////////////////////////////////////////////// 

[MetadataAttribute] 
[AttributeUsage(AttributeTargets.Method, AllowMultiple=true)] 
public class SupportedFileTypeAttribute : Attribute 
{ 
    public string FileTypeDescription { get; set; } 
    public string FileTypeMask { get; set; } 

    public SupportedFileTypeAttribute() 
     : base() 
    { } 
} 

問題是我不能有一個泛型參數在ImportMany屬性typeof運算。現在,我當然可以嘗試導入所有類型的裝載器並循環它們,但我無法想象這是一個優雅的解決方案。

什麼是最好的辦法呢?

在此先感謝。

+1

如果您沒有在'ImportMany'中指定類型並讓它嘗試匹配類型本身,會發生什麼?我從來沒有嘗試過這種情況,但我會很感興趣,看看是否有效。我也很喜歡阿迪的回答。 – burnttoast11

回答

2

我不認爲通過Loaders屬性循環是如此糟糕的事情。你只需要做一次(或者每次重組發生時,如果你設置了AllowRecomposition = True)。

我會有元數據指定它加載的數據的類型,並根據它提取所需的加載器。這基本上是元數據的用途。如果您使用Lazy<T, TMetadata>,則不會使用您不使用的類型。