Создание Autofac Lifetimescope, срок действия которого истекает со временем

У меня есть банк/коллекция, которая кэширует экземпляры объектов в памяти, поэтому каждому запросу не нужно возвращаться в хранилище данных. Я бы хотел, чтобы Autofac предоставил экземпляр этого банка, но затем истек его срок действия через x секунд, чтобы при следующем запросе был создан новый экземпляр. У меня возникли проблемы с настройкой LifetimeScope для достижения этой цели. Я прочитал это пару раз. Объект Bank на самом деле не зависит от единицы работы. В идеале он будет находиться «над» всеми единицами работы, кэшируя объекты внутри и между ними.

В настоящее время я использую описанный ниже подход, однако он не работает так, как я надеялся.

Может кто-нибудь указать мне в правильном направлении?

....
builder.Register(c =>
            {
                return new ORMapBank(c.Resolve<IORMapRoot>());
            }).InstancePerMatchingLifetimeScope(ExpireTimeTag.Tag());


        IContainer container = builder.Build();
        var TimedCache= RootScope.BeginLifetimeScope(ExpireTimeTag.Tag());
        DependencyResolver.SetResolver(new AutofacDependencyResolver(TimedCache));

....

public static class ExpireTimeTag
{
    static DateTime d = DateTime.Now;
    static Object tag = new Object();

    public static object Tag()
    {
        if (d.AddSeconds(10) < DateTime.Now)
        {
            CreateTag();
        return tag;
    }

    private static void CreateTag()
    {
        tag = new Object();
    }
}

Большое спасибо заранее.


person Damien Sawyer    schedule 04.07.2011    source источник


Ответы (1)


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

  • Создайте новый тип CachingORMapRoot, который реализует IORMapRoot
  • Добавьте конструктор, который принимает срок действия TimeSpan и экземпляр исходной реализации IORMapRoot.
  • Реализуйте членов для вызова базового экземпляра, а затем кэшируйте результаты соответственно для последующих вызовов (реализация будет зависеть от вашей технологии кэширования).
  • Зарегистрируйте этот тип в контейнере как IORMapRoot

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

person bentayloruk    schedule 04.07.2011
comment
Большое спасибо за это. Сработало удовольствие. Похоже, я сбился с пути. Теперь я могу попрощаться с состоянием сеанса! Это важно. Я чувствую, что должен зажечь свечу или что-то, чтобы отметить момент :-) - person Damien Sawyer; 05.07.2011
comment
Ура! Рад помочь. В следующий раз, когда кто-то скажет, что DI бесполезен и слишком сложен, вы можете рассказать им историю этого дня и свечи :) Конечно, для этого вам не нужен DI, но это упрощает добавление креста. -отказ от таких проблем, как кэширование, когда вам это нужно. - person bentayloruk; 05.07.2011
comment
Забавно, знаете ли. На днях у нас была веб-компания, которая консультировала нас по передовому опыту. Справедливости ради, они были очень хороши. Однако я был удивлен, когда ведущий технический специалист отклонил DI как ненужный и слишком сложный. Я почти закончил внедрение Autofac в своем текущем проекте и должен сказать, что был очень удивлен, как мало кода требуется. В общем, я думаю, что мне понадобилось всего 10-15 строк. Очень впечатляющая вещь :-) - person Damien Sawyer; 06.07.2011