2012-11-14 55 views
2

我的團隊正試圖找出在我們的自定義程序集中管理集中式常量(可能爲只讀靜態變量)的最佳方法。我們已經構建了一個處理體系結構,其中程序集動態加載到運行時。隨着數據通過我們的系統,一些程序集將信息寫入字典,然後傳遞給另一個程序集,該程序集將讀取數據並處理它。隨着我們的產品成熟並且我們的客戶需要不同的處理能力,我們將需要添加將被寫入/讀取的新數據字段。截至目前,我們在我們的核心dll中定義了常量,但這不會長期運行,因爲當我們獲得一個新的數據時,我們將不得不重新編譯核心dll,這樣我們的測試團隊將不得不完全退化測試整個應用程序,而不僅僅是測試新程序集提供的新功能。試圖找出一種方法來添加新常量,並知道正在編寫什麼數據,而無需重新編譯/部署任何我們不一定非要做的事情。程序集中的持續管理

我們考慮兩種選擇:

  1. 創建一個常數的DLL,它僅持有的常量。當我們 需要新的字段時,我們添加(從不刪除)到dll。這方面的下降 方面是,對dll的更改仍會影響整個系統,因此可能需要完整的迴歸測試。

  2. 讓每個程序集都公開所有讀取/寫入的字段, ,然後在開發人員集成期間查找名稱不匹配。對於 例如Assembly1由於對字典鍵 大小寫寫操作(字段1,字段2)和Assembly2讀取 (FIELD1,Filed2),引起的不匹配(字段1與FIELD1)。這將讓我們不必 一個常數組件,但它需要 不匹配驗證一些額外的代碼,並且似乎會導致耦合的一些位。

注:當我說的常量,我的意思並不是恆定的。根據我們最終的解決方案,我們可能會使用只讀靜態。

如果有人做了這樣的事,或有辦法的任何想法來做到這一點,我會欣賞你的輸入。我們的基本目標是通過僅部署新程序集來提供新功能。

+0

這些常量有哪些數據?爲什麼他們需要從其他程序集訪問? – Bobson

+0

Dictionary被設置爲。他們需要被不同的程序集訪問,因爲每個程序集都有特定的功能。例如,一個程序集將從xml文檔獲取傳入數據,並將其填充到字典中。然後另一個程序集將數據從字典中提取出來,放入一個自定義的csv文件中。這兩個程序集都需要知道他們正在訪問「PrimaryAddress」字段。如果那有意義的話。 – Means

+0

是否有一些令人信服的理由需要將這些值編譯爲常量?如何創建一個將常量保存爲鍵/值對的配置文件,然後使用「常量」DLL將這些數據讀入全局可用的字典中。然後,當添加新的常量時,不必重新編譯,迴歸測試可以限制爲驗證新常量的值不會干擾現有常量的值。 –

回答

0

基於您的評論,這真的聽起來像你應該使用DTO類。而不是值

dict["PrimaryAddress"] = "123 Someroad St."; 
dict["Name"] = "John Doe";` 

一本字典,你應該有一個對象

public class Address 
{ 
    public string PrimaryAddress { get; set; } 
    public string Name { get; set; } 
} 
.... 
new Address { 
    PrimaryAddress = "123 Someroad St.", 
    Name = "John Doe", 
}; 

爲了方便,你可以在你的核心庫中創建一個基類,它定義了一些標準行爲的所有類(例如,public Dictionary<string, string> ConvertToDictionary()用於遺留使用),然後每個程序集都可以從中繼承以創建它們自己的對象。然後,使用它們的程序集可以引用生成程序集並將其視爲特定類型,也可以將其視爲基本形式並使用基本功能。

+0

我明白你的意思,但不幸的是它不會爲我們工作。我在上面添加了一些澄清的評論,但基本上我們有一系列插入步驟來讀取/寫入數據到字典中。問題是我們不知道字典中會有什麼數據,因爲每個插件都可以提供不同的數據,並且用戶可以配置每個步驟使用的插件。我們需要的是每個插件(每個插件都是一個DLL)的一種方式,要知道如果「地址」在字典中,它將在「地址」鍵下,或者如果您正在編寫地址數據,則在「地址「鍵。 – Means

0

你可以做的是創建一個由在您的過程中的所有其它組件引用的一個組件。 (請注意,我假設應用程序中實際上只有一個進程)。 該程序集將公開一個類來保存這些「常數」。我們稱之爲會話。 這是我們在我們的項目中一項的使用實現:

//Defined in Dll appshared.dll  
public static class MyApplication 
{ 
    static AppSession appSession = new AppSession(); 
    public interface IAppSession 
    { 
     Object this[string key] 
     { 
      get; 
      set; 
     } 
    }; 
    sealed class AppSession : IAppSession 
    { 

     Dictionary<String, Object> _session = new Dictionary<string, object>(); 
     public AppSession() 
     { 
     } 
     public Object this[string key] 
     { 
      get 
      { 
       Object ret = null; 
       lock (_session) 
       { 
        _session.TryGetValue(key, out ret); 
       } 
       return ret; 
      } 
      set 
      { 
       if (key == null) 
        throw new ArgumentNullException(); 
       try 
       { 
        lock (_session) 
        { 
         if (value != null) 
          _session[key] = value; 
         else 
          _session.Remove(key); 
        } 
       } 
       catch (Exception eX) 
       { 
       } 
      } 
     } 
    }; 

    public static IAppSession Session 
    { 
     get 
     { 
      return appSession; 
     } 
    } 

}; 

而且你可以按如下方式使用它:

//In Dll A referencing appshared.dll 
MyApplication.Session["Const1"] = 1.0;//Set a global value 

//In Dll B referencing appshared.dll  
double const1 = (double)MyApplication["Const1"];//Read a global value - const1 will have the value set by Dll A 

//In Dll C referencing appshared.dll 
MyApplication.Session["Const1"] = null;//Delete a global value; 

當然你可以儲存的任何類型的數據你想要的。您可以輕鬆將其修改爲不區分大小寫。

我們還有一個更復雜的會話對象,它可以將值與配置文件同步,因此「常量」跨執行存儲。但是因爲你沒有提到你需要這樣的能力,所以這個簡單的類應該適合你。

+0

只有一個進程,但是我們處理的每一條數據都有一個新的字典。在上面的示例中,我們正在試圖找出如何管理dll的「Cost1」字符串,這樣所有dll都知道「Const1」儘可能少的耦合。或者你的例子可以做到這一點,我不明白你的例子。 – Means

+0

@Means這正是這個例子所做的。上面的類只在一個程序集中定義,但引用該程序集的所有程序集都可以訪問它並查詢它的內容。我會在答案中說清楚 –