2013-10-02 41 views
4

我的任務是模塊化一個C#應用程序,該應用程序是一個非常大的Delphi應用程序的重寫(數據庫有249個表!)。業務約束禁止完全重新設計.NET和更好的整體架構,所以我們基本上只是用C#中的Delphi應用程序模塊進行增量重寫模塊。在完成之前,該套件將包含待完成重寫的混合,以及我想要使用MEF集成的C#應用​​程序模塊。關於MEF策略和結構的問題

該應用程序關注考勤和訪問控制,並具有不同的業務領域,如「員工休假」和「訪客」。我認爲這些應該是單獨的項目,我們可以交換一個重寫的C#項目,並將其導入到MEF容器中。每個項目將導出一個IBusinessArea作爲最高級別的定義,然後這些將導出標準的共享接口,如IService,這些接口引入了業務領域中可用的服務,如CreateEmployee。每個服務將是一個類,以便使服務與容器的接口標準化,並且包含服務元數據,例如服務的Command,誰可以使用該服務的數據等。

我的標題在正確的方向,如果是這樣,我如何存儲和暴露IBusinessAreaIService元數據作爲類,而不是類型的元數據屬性?

+0

我的回答有幫助嗎? – Marc

回答

4

到目前爲止,你所說的一切聽起來都很合理。您將某些區域模塊化,在不同抽象層次上定義接口並使用不同接口導出每個模塊,即每個模塊都將被註冊爲它實現的多個接口。您將能夠根據您所需的抽象級別,獲得所有服務,所有業務領域等來解決您的模塊。因此,我認爲您正朝着正確的方向前進。

如何處理元數據? MEF提供元數據的導出,這似乎是合理的使用。也許我沒有完全理解它,但是我對MEF元數據導出做了非常糟糕的體驗。就我所知,MEF將元數據存儲爲鍵值對,其中鍵是一個字符串。

即使使用類型化的元數據導出和使用函數,元數據也不是真正的類型安全。假設您有一個名爲'PropertyA'的屬性的界面'IMetadata',並且您註冊了一個類型(爲了創造性,我們稱它爲Foo),這個類型用a中的相應屬性來裝飾,MEF調用類型安全,實現IMetadata的元數據)。現在假設你有第二個元數據接口'IMetadataB',它也有一個名爲PropertyA的屬性。如果您現在請求通過元數據IMetadataB請求解析Foo,您將首先獲得您註冊的實例,因爲MEF對元數據鍵值對中存在的PropertyA感到滿意,並構建了實現IMetadataB的相應代理元數據類型。長話短說,也許我對MEF不公平,但我停止使用MEF構建的元數據支持,並建議你也這樣做。當我處理非常複雜和冗長的元數據時,包括一些我想要與我導出的類緊密結合的類的文檔,我開發了一個對我來說非常好的系統,儘管它是一個有點非常規:

基本上,我爲我的元數據定義了一個接口和一個基類,比如MetadataBase,它帶有一個名爲Description的字符串屬性。

public class MetadataBase : IMetadata 
{ 
    public string Description { get; set; } 
} 

此後,對每個類別我想有元數據,我導出從該基類的類(FooMetadata)和XAML部分地限定它。然後,在XAML,我定義的屬性的類特定的值,例如:

<md:MetadataBase.Description> 
    The description of my class goes here 
</md:MetadataBase.Description> 

隨着自定義屬性,我涉及元數據類型到我的實際的類:

[Export(typeof(IFoo))] 
[AssociatedMetadata(typeof(FooMetadata))] 
public class Foo : IFoo 
{ 
    // Whatever 
} 

擴展方法爲對象,您可以通過反射讀取的元數據:

public static IMetadata GetMetadata(this object objectWithMetadata) 
{ 
    // Read attribute type 
    // Create instance of the metadata type, i.e. FooMetadata 
    // A caching mechanism can be implemented, if needed, but, honestly, 
    // my really big metadata objects including images and stuff like this 
    // are created within 3-5 ms 
    // Return this instance 
} 

現在,你基本上沒有,你可以看到它有這樣的元數據的任何對象的元數據:

var myObjectsMetadata = myObject.GetMetadata(); 

當你讓你的AssociatedMetadataAttribute實現一個接口並且使用這個接口的元數據註冊你的類型時,你可以在MEF中利用這個元數據。沒有什麼會混淆,因爲對於擁有一個屬性而沒有其他任何東西(類型)的所有東西都有一種類型的元數據。

這個解決方案並不是一切的正確方法,但我喜歡它,你的問題是展示它的好機會。希望能幫助到你!

+0

對我來說,MEF導出元數據最強大的功能就是您可以在不創建導出零件的情況下訪問它們。對於附加場景,這非常有用。你提出的關於類型安全性的觀點是有效的,並且應該在MEF的文檔中予以說明,以便新人有更輕鬆的時間。也就是說一個或兩個元數據類應該足夠用於大多數應用程序。如果我沒有弄錯,你的方法是使用一個IMetadata。我對WPF沒有經驗,但不知道您的方法是否可以用MEF Export Metadata取代。 –

+0

@PanosRontogiannis,正確,我正在使用一個元數據接口。您仍然可以通過MEF導出元數據並訪問它,而無需實際解析導出的部分。對我而言,這是兩全其美的。 – Marc