1

我最近决定使用来自城堡的拦截器功能来实现缓存。它工作正常。

我的问题:如果我想避免特定呼叫的拦截器,您建议使用什么策略?

我已经确定我可以有两个给定服务的实现,一个支持缓存方面,一个不支持。然后我可以从任何地方呼叫合适的人。我不喜欢那样有很多原因。

我可以在我知道缓存无效的时候使缓存无效,但是我无法按照这种思路提出一个好的解决方案,仍然让缓存问题远离我的代码。

4

2 回答 2

2

我通常使用装饰器来处理缓存问题。

关于删除/使缓存项无效,我提出了一个基于事件的解决方案:
真实服务为那些改变系统的行为公开事件(例如添加或更新项目),装饰服务(缓存策略)将自己注册到这些事件以管理缓存.

于 2013-09-05T07:53:42.407 回答
0

我在城堡温莎拦截器的帮助下使用了缓存,我也遇到了同样的问题。通常,服务不应该知道依赖项是否启用了缓存。这将违反单一责任原则。

如果您对此代码气味不满意,您可以:

将您的组件注册为具有和不具有缓存的命名组件。然后你可以有选择地使用那些命名的组件。

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();
}
于 2013-09-07T13:15:25.497 回答