2014-06-18 40 views
0

我正在使用Dynacache來緩存將最終從服務調用返回的數據 - 以使事情正常工作我只是將返回的數據存根。我正在使用SimpleInjector進行DI,並且已經註冊了Dynacache,就像我在之前的回答中指出的那樣。questionDynacache不會緩存數據

所以我在我的解決方案中有一個集成項目,它包含我想要緩存的方法 - 目前看起來像如下:

[CacheableMethod(30)] 
public virtual List<MyResponse> GetDataByAccountNumber(int accountNumber) 
{ 
    var response = StubResposne(); 

    return response; 
} 

上面的實現Dynacache應緩存數據30秒,然後清除它。但是,如果我在第一次在我的私人StubResponse()方法的第一行設置一個斷點時,我第一次使用該數據的網頁將按照預期命中斷點並返回數據。但是,如果我再次刷新頁面,我期待着數據會被緩存(在30秒內),那麼斷點不會被打到,但是每次都會打到?

有沒有什麼不正確的,我如何使用Dynacache?

+0

哪裏是緩存數據?它是否緩存在「MemoryCacheService」實例中?如果這是真的,這可能是問題,因爲根據您以前的問題,您將其註冊爲瞬態。也許它需要是單身人士,但請注意,這是你必須從閱讀Dynacache文檔中找到的東西。也許這種類型不是線程安全的,你需要有多個實例。 – Steven

+0

hi @Steven - 是的,我期望它在MemoryCacheService中 - 我改變了容器。從之前的答案註冊到container.RegisterSingle - 但是我仍然看到在30秒內刷新頁面的斷點 - 不幸的是我沒有看到DynaCache的很多文檔? http://dynacache.codeplex.com/wikipage?title=Example%20using%20Unity&referringTitle=Documentation –

回答

0

對於SimpleInjector註冊,應當按以下步驟進行:

container.RegisterSingle<IDynaCacheService>(new MemoryCacheService()); 
container.Register(typeof(ITestClass), Cacheable.CreateType<TestClass>()); 

一旦我做到了這一點緩存都按預期。

更新了完整的測試示例程序

using System; 

namespace DynaCacheSimpleInjector 

{ 
    using System.Threading; 


using DynaCache; 

using SimpleInjector; 

class Program 
{ 
    static void Main() 
    { 
     var container = new Container(); 

     container.RegisterSingle<IDynaCacheService>(new MemoryCacheService()); 
     container.Register(typeof(ITestClass), Cacheable.CreateType<TestClass>()); 

     var instance = container.GetInstance<ITestClass>(); 

     for (var i = 0; i < 10; i++) 
     { 
      // Every 2 seconds the output will change 
      Console.WriteLine(instance.GetData(53)); 
      Thread.Sleep(500); 
     } 
    } 
} 

public class TestClass : ITestClass 
{ 
    [CacheableMethod(2)] 
    public virtual string GetData(int id) 
    { 
     return String.Format("{0} - produced at {1}", id, DateTime.Now); 
    } 
} 

public interface ITestClass 
{ 
    string GetData(int id); 
} 

}

+0

你可以添加一些更多的信息給這個答案,因爲我不能使用你所顯示的代碼來工作。每次我請求一個「ITestClass」實例並調用「GetDataByAccountNumber」時,它都不會返回緩存的響應。 – qujck

+0

@qujck - 更新了示例程序 - 這對我很有用 –

+0

這與我在回答中包含的第一個測試完全相同,如果我從同一個實例調用方法兩次,則第二次獲取緩存的結果。您從容器中獲取一個實例,並在同一個實例上重複調用相同的方法。您不需要將'IDynaCacheService'註冊爲Singleton來實現該功能。 – qujck

2

這可能是由於您註冊包含GetDataByAccountNumber方法的類的方式。

第一次測試工作 - 如果我來自同一個實例調用該方法兩次我得到緩存的結果返回第二次,

[Test] 
public void GetDataByAccountNumber_CalledTwiceSameInstance_ReturnsCacheSecondTime() 
{ 
    var container = new Container(); 

    container.Register<IDynaCacheService>(() => new MemoryCacheService()); 
    container.Register(typeof(TestClass), Cacheable.CreateType<TestClass>()); 

    var instance = container.GetInstance<TestClass>(); 

    instance.GetDataByAccountNumber(1); 
    instance.GetDataByAccountNumber(2); 

    Assert.That(instance.CallerId == 1); 
} 

如果我得到2種不同的情況下,從容器中再沒有緩存完成

public void GetDataByAccountNumber_CalledTwiceDifferentInstance_DoesNotReturnFromCache() 
{ 
    var container = new Container(); 

    container.Register<IDynaCacheService>(() => new MemoryCacheService()); 
    container.Register(typeof(TestClass), Cacheable.CreateType<TestClass>()); 

    var instance1 = container.GetInstance<TestClass>(); 

    instance1.GetDataByAccountNumber(1); 

    var instance2 = container.GetInstance<TestClass>(); 

    instance2.GetDataByAccountNumber(2); 

    Assert.That(instance2.CallerId == 2); 
} 

測試類看起來像這樣

public class TestClass 
{ 
    public int CallerId = 0; 

    [CacheableMethod(30)] // TODO - put to 20 minutes and have value in WebConfig as constant 
    public virtual List<MyResponse> GetDataByAccountNumber(int callerId) 
    { 
     CallerId = callerId; 

     var response = StubResponse(); 

     return response; 
    } 

    // ... 

只需註冊一個生命週期範圍似乎與dynacache不兼容。在這種測試方法的容器返回壽命的範圍,但沒有被高速緩存方法的結果中每個呼叫的同一個實例....

[Test] 
public void GetDataByAccountNumber_CalledTwiceLifetimeScopedInstance_ReturnsCacheSecondTime() 
{ 
    var container = new Container(); 

    container.Register<IDynaCacheService>(() => new MemoryCacheService()); 
    container.Register(typeof(TestClass), Cacheable.CreateType<TestClass>(), new LifetimeScopeLifestyle()); 

    using (container.BeginLifetimeScope()) 
    { 
     var instance1 = container.GetInstance<TestClass>(); 

     instance1.GetDataByAccountNumber(1); 

     var instance2 = container.GetInstance<TestClass>(); 

     instance2.GetDataByAccountNumber(2); 

     // the container does return the same instance 
     Assert.That(instance1, Is.EqualTo(instance2)); 
     // but the caching does not work 
     Assert.That(instance2.CallerId, Is.EqualTo(1)); 
    } 
} 

我的建議是,你實現緩存與裝飾這是真正的輕鬆與簡單的噴油器 - 讀@文章史蒂芬的開始here

+0

我還沒有看到你發佈的文章,但是你建議擺脫Dynacache並使用SimpleInjector來實現緩存 –

+0

@Ctrl_Alt_Defeat是的。我認爲Dynacache會生成某種形式的動態代理,儘管它很酷,但它在某個時間點會帶來額外的複雜性。 – qujck

+0

會有意思,看看你是否可以重新運行你的代碼,看看它是否按預期工作註冊dynacache,正如我在答案中所示的那樣? –