我正在使用Dynacache来缓存最终将从服务调用返回的数据 - 让事情正常工作我只是将返回的数据存根。我正在使用SimpleInjector进行DI并使用它注册了Dynacache,正如我之前的question
所给出的答案所指出的那样所以我的解决方案中有一个集成项目,其中包含我想要缓存的方法 - 目前看起来如下:
[CacheableMethod(30)]
public virtual List<MyResponse> GetDataByAccountNumber(int accountNumber)
{
var response = StubResposne();
return response;
}
通过上面的实现,Dynacache应该将数据缓存30秒然后清除它。但是,如果我在我的私有StubResponse()方法的第一行设置断点,我第一次点击使用该数据的网页时,断点会按预期命中并返回数据。但是,如果我再次立即刷新页面,我期待数据将被缓存(因为它在30秒内),那么断点不会被击中但是每次都会被击中?
我使用Dynacache的方式有什么不对吗?
答案 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);
}
}