Dynacache不会缓存数据

时间:2014-06-18 10:27:02

标签: c# .net caching simple-injector dynacache

我正在使用Dynacache来缓存最终将从服务调用返回的数据 - 让事情正常工作我只是将返回的数据存根。我正在使用SimpleInjector进行DI并使用它注册了Dynacache,正如我之前的question

所给出的答案所指出的那样

所以我的解决方案中有一个集成项目,其中包含我想要缓存的方法 - 目前看起来如下:

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

    return response;
}

通过上面的实现,Dynacache应该将数据缓存30秒然后清除它。但是,如果我在我的私有StubResponse()方法的第一行设置断点,我第一次点击使用该数据的网页时,断点会按预期命中并返回数据。但是,如果我再次立即刷新页面,我期待数据将被缓存(因为它在30秒内),那么断点不会被击中但是每次都会被击中?

我使用Dynacache的方式有什么不对吗?

2 个答案:

答案 0 :(得分: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));
    }
}

我的建议是你使用装饰器实现缓存,使用Simple Injector非常容易 - 阅读@ Steven的文章here

答案 1 :(得分: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);
}

}