创建一个随时间过期的Autofac生命周期范围

4
我有一个银行/集合,可以将对象实例缓存在内存中,以便每个请求不需要返回数据存储区。我希望Autofac提供此银行的实例,但在x秒后使其过期,以便在下一个请求时创建新的实例。我很难理解如何设置LifetimeScope来实现这一点。我已经阅读了这篇文章几次。银行对象并不是真正受到工作单元的约束。它理想地位于所有工作单元“上方”,在其中和跨其中缓存对象。
我目前正在使用下面的方法,但它并没有像我希望的那样工作。请问有人能指点我正确的方向吗?
....
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();
    }
}

非常感谢您的提前帮助。
1个回答

7
通常使用缓存装饰器来实现这种行为。假设您的 IORMapRoot 负责获取相关数据(但如果是 ORMapBank,则同样适用),则可以执行以下操作:
  • 创建一个新类型 CachingORMapRoot,它实现了 IORMapRoot
  • 添加一个构造函数,该函数接受到期时间 TimeSpan 和原始的 IORMapRoot 实现的实例。
  • 实现成员以调用底层实例,然后相应地缓存结果以供后续调用使用(实现将因缓存技术而异)。
  • 将此类型注册为容器中的 IORMapRoot
这是一种非常干净的方式来实现这样的缓存。它还使得 在缓存和非缓存实现之间切换 变得容易。

1
非常感谢您的帮助,效果很好。看起来我完全偏离了轨道。现在我可以告别会话状态了!这是一个重要的时刻。我觉得我应该点一支蜡烛或者什么东西来纪念这个时刻 :-) - Damien Sawyer
太好了!很高兴能帮上忙。下次有人说“DI没有用,而且太复杂”,你可以告诉他们这一天和蜡烛的故事 :) 当然,你不需要 DI 来做到这一点,但是当你需要添加跨领域关注点(如缓存)时,它会让它变得更容易。 - bentayloruk
1
你知道吗,有一家网络公司前几天来这里咨询最佳实践,他们非常专业。但是当主要技术人员否定依赖注入不必要且过于复杂时,我还是很惊讶的。我现在正在我的当前项目中实施Autofac,我必须说,我真的很惊讶它所需的代码量是多么少。总共只需要10-15行代码。非常令人印象深刻 :-) - Damien Sawyer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接