2013-09-05 8 views
1

Недавно я решил реализовать кеширование с использованием функции перехватчика из замка. Он работает нормально.Замок Виндзорский перехватчик для решения вопроса кеширования

Мой вопрос: Если бы я хотел избежать перехватчика для конкретного вызова, какую стратегию вы бы предложили использовать?

Я уже определил, что у меня могут быть две реализации данного сервиса, поддерживающие аспект кеширования, и тот, который этого не делает. Тогда я мог бы позвонить соответствующему из любого места. Мне это не нравится по многим причинам.

Я был бы в порядке с аннулированием кеша в тот момент, когда я знал, что это будет недействительно, но я не смог найти хорошее решение, следуя этой линии мышления, которая все еще сохраняла проблемы кэширования из моего кода.

ответ

2

Обычно я использую декораторы для задач кэширования.

об удалении/недействительности элемента кэша я вышел с событием решения на основе:
реальная служба выставляет события для этих моделей поведения, изменяющей систему (напр добавления или обновления элемента), декоратор служба (стратегия кэширования) регистрирует itseself в эти события для управления кешем.

+0

К сожалению, Windsor не всегда облегчает работу с декораторами, особенно когда речь идет о применении общих декораторов к универсальному интерфейсу. – Steven

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 vs IServiceWithCache.

2. Реализовать одноэлементное безопасное «кэширование включено» для включения/отключения кэширования. Если вы хотите издеваться над этим сервисом, вы можете реализовать его с помощью контекста окружения.

CacheSettings.Disable(); 
try 
{ 
    ... 
} 
finally 
{ 
    CacheSettings.Enable(); 
}