2011-08-26 83 views
0

作爲一個獨立軟件開發商,我希望能夠使用AppFabric Caching Service編寫我的中間層,但隨後能夠部署在小型(單服務器)環境中,而無需部署AppFabric Cache Server。對我來說,緩存客戶端的「僅內存」版本對於獨立開發來說也是理想的。然而,到目前爲止我所做的所有研究都意味着我必須加載一個真正的緩存服務器來使一些apis可以工作,而且目前的「本地」選項並不適合什麼我想要。AppFabric Cache獨立模式?

在我看來,我期待的工作方式與aspx會話緩存類似,因爲開箱即用機制在內存中,然後您可以選擇配置較早的外部流程提供程序,或者SQL提供程序,現在是AppFabric提供程序,隨着您的向上移動,可提供更好,更好的可伸縮性。這對aspx會話很有用。

我正確地認爲在AppFabric緩存的「小」環境中沒有用於編程和部署的等效解決方案嗎?

回答

5

有一些在這個問題上提出的問題,讓我們看看我們是否能夠解決這些問題......

第一最重要的是,作爲Frode correctly points out,您可以在一臺服務器上非常高興地運行AppFabric實例 - 這正是我大部分時間玩API的原因。很顯然,高可用性功能不太可能,但從問題本身來看,我認爲您已經接受了這一點。

其次,您不能使用AppFabric API對本地緩存進行訪問 - 本地緩存僅用於保存AppFabric客戶端通過線路傳輸到專用的AppFabric緩存服務器。

現在,可配置的緩存,我認爲這是最有趣的部分。我認爲你想在這裏做的是將緩存上的操作從緩存本身分離到一個通用接口,然後在設計時針對接口編寫代碼,並且在運行時根據應用程序中的信息創建緩存的.config/web.config中。

因此,讓我們先來定義我們的接口開始:

public interface IGenericCache 
{ 
    void Add(string key, object value); 
    void Remove(string key); 
    Object Get(string key); 
    void Update(string key, object value); 
} 

現在我們可以利用AppFabric的定義一對夫婦的實現,一個使用的MemoryCache和一個。

using System.Runtime.Caching; 

class GenericMemoryCache : IGenericCache 
{ 
    public void Add(string key, object value) 
    { 
     MemoryCache cache = new MemoryCache("GenericMemoryCache"); 

     cache.Add(key, value, null, null); 
    } 

    public void Remove(string key) 
    { 
     MemoryCache cache = new MemoryCache("GenericMemoryCache"); 

     cache.Remove(key, null); 
    } 

    public object Get(string key) 
    { 
     MemoryCache cache = new MemoryCache("GenericMemoryCache"); 

     return cache.Get(key, null); 
    } 

    public void Update(string key, object value) 
    { 
     MemoryCache cache = new MemoryCache("GenericMemoryCache"); 

     cache.Set(key, value, null, null); 
    } 
} 

using Microsoft.ApplicationServer.Caching; 

class GenericAppFabricCache : IGenericCache 
{ 
    private DataCacheFactory factory; 
    private DataCache cache; 

    public GenericAppFabricCache() 
    { 
     factory = new DataCacheFactory(); 
     cache = factory.GetCache("GenericAppFabricCache"); 
    } 

    public void Add(string key, object value) 
    { 
     cache.Add(key, value); 
    } 

    public void Remove(string key) 
    { 
     cache.Remove(key); 
    } 

    public object Get(string key) 
    { 
     return cache.Get(key); 
    } 

    public void Update(string key, object value) 
    { 
     cache.Put(key, value); 
    } 
} 

而且我們可以繼續下去寫與ASP.NET緩存,nCache的,memcached的IGenericCache實現...

現在我們添加使用反射創建其中的一個實例的工廠類基於來自app.config/web.config的值的緩存。

class CacheFactory 
{ 
    private static IGenericCache cache; 

    public static IGenericCache GetCache() 
    { 
     if (cache == null) 
     { 
      // Read the assembly and class names from the config file 
      string assemblyName = ConfigurationManager.AppSettings["CacheAssemblyName"]; 
      string className = ConfigurationManager.AppSettings["CacheClassName"]; 

      // Load the assembly, and then instantiate the implementation of IGenericCache 
      Assembly assembly = Assembly.LoadFrom(assemblyName); 
      cache = (IGenericCache) assembly.CreateInstance(className); 
     } 
     return cache; 
    } 
} 

任何地方的客戶端代碼需要使用高速緩存,所有需要的是CacheFactory.GetCache一個電話,在配置文件中指定的緩存會被退回,但客戶並不需要知道哪個緩存這是因爲客戶端代碼都是針對接口編寫的。這意味着只需更改配置文件中的設置即可擴展緩存。

基本上我們在這裏寫的是一個用於緩存的插件模型,但請注意,您將犧牲功能的靈活性。界面必須或多或少是最低的共同標準 - 你失去了使用AppFabric的併發模型或標記API的能力。

this article中有針對接口進行編程的優秀且更完整的討論。

+0

菲爾,感謝您的詳細解答。你所提出的基本上是我試圖避免的,但你已經證實了我的研究。在IIS中實現時,多線程方面會給實現增加一些複雜性,但我認爲.Net 4.0 ConcurrentDictionary應該有助於使這幾乎微不足道...需要重新編寫更多。對於遲到的回覆抱歉,我以爲我會收到電子郵件通知的答案...新手問題! –

0

我們有一個設置在這裏我們只運行一個服務器上的應用程序結構緩存...