2009-07-31 37 views
2

背景簡介:MEF:加載部件(插件),它具有不同的特性

我的團隊已經決定,爲了添加新提供了一個可擴展的模型使用微軟的託管擴展性框架(MEF) 「提供者」加入我們的系統。

這使我們能夠相對容易地插入新的第三方提供商。

注意:MEF的簡單使用和啓動方式給我留下了深刻的印象。

我的問題:

由於這些提供商通常具有不同的性質與它們相關的,在運行時加載這些供應商到系統中,當我們需要訪問提供商的數據流和屬性。

由於不同的屬性,應該採取什麼方法來與所述提供者插件一起工作?注意到他們都做了類似的工作。

我的解決方案:

創建該供應商必須符合的接口,導致「包裝」周圍的每個產生一個一致的界面/ 編程模型一起工作的第三方供應商的創建每個供應商。

插件=第三方數據源(提供程序)+通用接口實現。

+ ve: 不需要針對所述插件的更復雜的基於反射的動態「插件」。

-ve: 必須爲每個提供者編寫包裝。 (我們需要添加不管MEF導出代碼)

進一步注:

對我來說,接口/包裝的方法是最簡單的,但我已被告知,調查反映爲基礎的方法,其可能利用反射來發現運行時可能暴露給系統的屬性。

我不贊成任何一種解決方案,但我會有興趣聽到社區的想法(其中大部分比我更有經驗)。

謝謝。

回答

1

目前尚不清楚您所談論的是什麼「屬性」和「數據流」,但依然如此。

是的,通用接口總是一件好事。既然你有這些「屬性」,這樣,我建議如下:

interface IProperty 
{ 
    string Name { get; } 
    object Value { get; } 
} 

interface IDataStreamProvider 
{ 
    Stream OpenStream(); 
} 

interface IPlugin 
{ 
    ReadOnlyCollection<IProperty> Properties { get; } 

    ReadOnlyCollection<IDataStreamProvider> DataStreams { get; } 
} 

說到「包裝」的:我不明白這些的意圖。所有第三方插件必須實現IPlugin接口,並且必須以ExportAttributePluginAttribute裝飾在此:

class PluginAttribute : ExportAttribute 
{ 
    public PluginAttribute() : 
     base(typeof(IPlugin)) 
    { 
    } 
} 

反射應該被避免的,因爲維修的擔憂儘可能。

1

我所做的添加信息的方法是爲插件製作一些自定義屬性,然後在插件加載時用MEF讀取這些屬性。您可以在屬性類中添加任何內容,例如名稱,枚舉,整數,其他字符串,並且它非常易於使用。但要小心,新預覽6確實改變了這些處理方式中的一些事情。

[MetadataAttribute] 
public class MyMetadataAttribute : Attribute 
{ 
    public MyType MyUsage { get; set; } 
} 

public interface IMyMetadataView 
{ 
    MyType MyUsage { get; } 
} 

public enum MyType 
{ 
    Undefined, 
    TypeOne, 
    TypeTwo 
} 

然後在插件,你可以將其定義是這樣的...

[Export(typeof(IMyInterface))] 
[MyMetadataAttribute(MyUsage = MyType.TypeOne)] 
public class PluginClass: IMyInterface 
{ 
} 

你需要的東西添加到導入,然後還

[ImportMany(AllowRecomposition = true)] 
public IEnumerable<Lazy<IMyInterface, IMyMetadataView>> plugins { get; set; } 

然後,您可以使用數據直接針對每個插件

var typeOnePlugin = plugins.FirstOrDefault(p => p.Metadata.MyUsage == MyType.TypeOne); 

再次,這是使用預覽6在7月出來的方式。

2

其實在預覽版6中,我們已經打開了導出並允許您創建包含元數據的自定義導出屬性,從而免除了部分作者添加單獨導出的需要。我們所有的導入屬性也都是開封的。

[MetadataAttribute] 
[AttributeUsage(AllowMultiple=false)] 
public class RuleAttribute : ExportAttribute { 
    public RuleAttribute(string name, string description) { 
    Name=name; 
    Description=description; 

    } : base(typeof(IRule)) 

    public string Name {get;private set;} 
    public string Description {get; private set;} 
} 

RuleAttribute以上導出IRule,並且還允許提供名稱元數據。然後

的使用將是以下:

[Rule("AddOneRule", "Adds one to the value")] 
public class AddOneRule { 
} 

HTH 格倫

+0

次要此外,RuleAttribute類也應標有: [AttributeUsage(的AllowMultiple =假)] – 2009-08-14 19:44:07

相關問題