我最近决定使用来自城堡的拦截器功能来实现缓存。它工作正常。
我的问题:如果我想避免特定呼叫的拦截器,您建议使用什么策略?
我已经确定我可以有两个给定服务的实现,一个支持缓存方面,一个不支持。然后我可以从任何地方呼叫合适的人。我不喜欢那样有很多原因。
我可以在我知道缓存无效的时候使缓存无效,但是我无法按照这种思路提出一个好的解决方案,仍然让缓存问题远离我的代码。
我最近决定使用来自城堡的拦截器功能来实现缓存。它工作正常。
我的问题:如果我想避免特定呼叫的拦截器,您建议使用什么策略?
我已经确定我可以有两个给定服务的实现,一个支持缓存方面,一个不支持。然后我可以从任何地方呼叫合适的人。我不喜欢那样有很多原因。
我可以在我知道缓存无效的时候使缓存无效,但是我无法按照这种思路提出一个好的解决方案,仍然让缓存问题远离我的代码。
我通常使用装饰器来处理缓存问题。
关于删除/使缓存项无效,我提出了一个基于事件的解决方案:
真实服务为那些改变系统的行为公开事件(例如添加或更新项目),装饰服务(缓存策略)将自己注册到这些事件以管理缓存.
我在城堡温莎拦截器的帮助下使用了缓存,我也遇到了同样的问题。通常,服务不应该知道依赖项是否启用了缓存。这将违反单一责任原则。
如果您对此代码气味不满意,您可以:
将您的组件注册为具有和不具有缓存的命名组件。然后你可以有选择地使用那些命名的组件。
var container = new WindsorContainer();
container.Register(Component.For<CachingInterceptor>()
.Instance(new CachingInterceptor(new Cache(TimeoutStyle.RenewTimoutOnQuery, TimeSpan.FromSeconds(3)))));
container.Register(Component.For<IRepo>().ImplementedBy<Repo>().Named("Without"));
container.Register(Component.For<IRepo>().ImplementedBy<Repo>().Interceptors<CachingInterceptor>().Named("With"));
container.Register(Component.For<Service>());
container.Register(Component.For<Game>().DependsOn(Property.ForKey<IRepo>().Is("With")));
var service = container.Resolve<Service>();
var game = container.Resolve<Game>();
Console.WriteLine("Cache is not used");
service.Invoke();
service.Invoke();
Console.WriteLine();
Console.WriteLine("Cache is used");
game.Invoke();
game.Invoke();
我在 github 上有这个项目: https ://github.com/kobbikobb/Caching
如果您对这种代码气味感到满意,您可以:
1. 根据我何时要使用缓存,我使用了不同的接口。IService 与 IServiceWithCache。
2. 实现一个单例安全的“缓存启用”服务来启用/禁用缓存。如果你想模拟这个服务,你可以通过环境上下文来实现它。
CacheSettings.Disable();
try
{
...
}
finally
{
CacheSettings.Enable();
}