2010-09-06 28 views
3

定義插件命令(包括鏈接插件)[我已經閱讀MEF先前的文章VS MAF VS DI等,他們不幫我具體的問題]淨插件框架的選擇,使

我要找編寫一個可擴展的.Net應用程序(可能是控制檯或Windoes服務)。這是一個通宵/時間表應用程序,用於從數據庫中提取數據,對數據進行處理,然後將其輸出(或傳遞給另一個系統)。

我不確定什麼是爲插件定義此過程的最佳方法。的組件包括:

  • 任務 - 實際任務的定義,包含插件定義,和基於事件的標誌上時運行(EOD,EOW,EOM)
  • - 的源數據(一個任務將有一個到多個來源),這可能是一個SQL查詢/存儲過程,Web服務或者一個文件。我看到這輸出一個數據表。
  • 後期處理 - 需要在源輸出上完成的處理(一個任務將具有非到多個後處理步驟),這可能是一個聚合器或某種特定的處理。這會收到一個數據集(包含上一步中的數據表)。由於依賴關係,這些必須按特定順序運行。
  • 目標 - 最終的結果(也一對多),這可能是一個SQL語句/存儲過程,一個專有的數據負載,電子郵件,輸出文件或Web服務

爲了簡化它,我寧願插件可以從配置文件讀取,這意味着我不需要知道什麼連接字符串(和其他細節)傳遞給插件。

我看過MEF,MAF,DI或者只是定義了我自己的框架。在這個階段,我傾向於開發自己的產品,只是想知道我是否錯過了什麼?

我實際上想使用MEF,但是因爲我需要定義我的任務(即任務鏈接指向哪個源鏈接到哪個PostProcess鏈接到哪個目標),並且也無法訪問配置。我看到MEF Primatives和Type Catalogs讓我成爲其中的一部分,但似乎並沒有幫助我鏈接插件。 MEF是一個有效的選擇嗎?

回答

3

MEF絕對是一個有效的選擇。不過,我不認爲MEF的設計是一個完全成熟的插件系統,它是一個很好的起點! MEF處理所有骯髒的裝配加載和處理,但是任何特定的先決條件都需要手動檢查。爲此我建議使用元數據。元數據允許您使用可以讀取的出口信息在導入前(MEF Metadata

[Export(typeof(ITask))] 
[ExportMetadata("Requires", "source1")] 
public class Task1: ITask 
{ 
    ... 
} 

通過與MEF是簡單的路過的配置相關聯。宿主應用程序可以導出它自己,所有插件都可以導入它並訪問其接口。見我下面的例子:

接口:

public interface IMainApp 
{ 
    ConfigClass Config { get; set; } 
} 

主機應用程序:

[Export(typeof(IMainApp))] 
public class Host : IMainApp 
{ 
    public Host() 
    { /* Compose parts here..? */ } 

    public ConfigClass Config { get; set; } 

    [Import(typeof(IModule))] 
    public List<IModule> LoadedModules { get; set; } 
} 

插件組裝:

[Export(typeof(IModule))] 
public class Module : IModule 
{   
    public Module() { } 

    [Import(typeof(IMainApp))] 
    public IMainApp Host { get; set; } 

    public void DoSomething() 
    { 
     Host.Config... // use config here 
    } 
} 
+0

感謝您的答覆。 MEF元數據看起來非常有趣,我可以看到它的用途。不過,我認爲這不會解決我的問題。 – 2010-09-07 13:00:12

+0

我希望能夠使用不同的插件組合來定義任務,而無需編寫任何代碼。即Task1將Source1&Source2插入PreProcess1到Target1中,Task2將Source2插入PreProcess2插入Target1&Target2,Task3將Source3插入PreProcess2 Target2。但是任務定義「元數據」希望是某種配置,而不需要編譯代碼。我認爲我需要在沒有框架的情況下做到這一點,我仍然可以通過合同來做到這一點,至少可以使其具有可擴展性和可重用性。 – 2010-09-07 13:01:08

1

這聽起來像你想做的事就是我們所說的明確的連線。 MEF默認情況下不支持這種方式,所以你必須跳過一些環節才能做到這一點。我相信MEF Contrib上有一個配置驅動的編程模型,它可以幫助你。

+0

我以前看過,最接近我發現的要求是 - [MEF的可配置類型目錄](http://randomactsofcoding.blogspot.com/2010/01/configurable-type-catalog-for-mef.html) 。我想知道是否可以在配置文件中爲每個任務定義定義一個新的自定義部分,然後只添加我感興趣的類型/部分。我想我也可以在運行時使用Reflection來填充元數據,以強制執行我可能具有的任何鏈接規則(以確保按照上述評論中的示例遵循正確的順序)。 – 2010-09-07 13:48:07

1

您可能想看看Mono.Addins。你可以爲每個部分定義一個擴展點(所以插件可以定義新類型的源或目標),然後你可以創建一個擴展點來定義任務。在後面的擴展點中,您將定義每個任務以及它們與源和目標的關係。

例如,源可以在插件定義是這樣的:

[Extension (Id="MySource")] 
class MySource: ISource 
{ 
    ... 
} 

以及用於定義任務的擴展點可能是這樣的:

<Extension path="/MyApp/Tasks"> 
    <Task id="someTask"> 
     <Source sourceId="MySource" /> 
     <Target targetId="MyTarget" /> 
    </Task> 
    ... 
</Extension>