代码之家  ›  专栏  ›  技术社区  ›  Per Hornshøj-Schierbeck

在类库中正确实现缓存以用于ASP.NET应用程序

  •  8
  • Per Hornshøj-Schierbeck  · 技术社区  · 17 年前

    我正在一个类库中实现一个缓存,我在一个ASP.NET应用程序中使用它。

    我用一个静态方法将缓存对象创建为一个单例模式来更新缓存,它实际上只是用我需要缓存的数据集合加载一个成员变量/属性(当然还有一些锁定逻辑)。我觉得这是一个很好的方法,因为我可以通过电话访问我的数据

    MyCacheObject.Instance.MyDataCollection
    

    我正在创建一个新的缓存对象来存储由某个键分区的大量数据。我要说的是,我正在创建一个新的缓存,但这个缓存不会一次加载所有数据,而是为每个访问的键存储一个集合。

    MyOtherCacheObject.Instance.MyOtherDataCollection(indexkey)
    

    这一次提出了关于垃圾收集的问题。因为我存储了大量的数据,如果它突然被收集起来,这不是浪费吗?因为它只是一个单例模式,所以没有任何东西可以确保数据保持在缓存中。

    所以我的问题是——什么是实现缓存来处理这种情况的最佳实践?我真的不喜欢一个复杂的解决方案,我知道System.Web中有缓存,但这似乎有点“关闭”,因为这只是一个类库,或者你认为呢?

    2 回复  |  直到 17 年前
        1
  •  9
  •   Sergio Acosta    17 年前

    我认为,最佳解决方案应具有以下特点:

    • 使用平台提供的可用缓存服务,尝试避免编写自己的缓存服务。

    • 不要将类库与System.Web耦合,以使层保持一致。

    • 但是,如果类库在ASP.NET应用程序内部运行,则解决方案不应要求启用另一个缓存实现(例如,企业库缓存应用程序块),这需要额外的配置和设置。

    因此,我将使用IOC策略,以允许类库根据运行环境使用不同的缓存实现。

    假设您将抽象缓存契约定义为:

    public interface ICacheService 
    {
        AddItem(...);
    }
    

    您可以提供基于System.Web的实现:

    public AspNetBasedCacheService : ICacheService
    {
        AddItem(...)
        {
            // Implementation that uses the HttpContext.Cache object
        }
     }
    

    然后将该实现“发布”为singleton。请注意,与原始方法的不同之处在于,singleton只是对基于ASP.NET缓存服务的实现的引用,而不是完整的“缓存对象”。

    public class ChacheServiceProvider 
    {
        public static IChacheService Instance {get; set;}
    
    }
    

    您必须通过执行延迟初始化或在应用程序启动时(在global.asax.cs中)初始化chaching实现。

    而且每个域组件都可以使用发布的缓存服务,而不知道它是基于System.Web实现的。

    // inside your class library:
    IChacheService chache = CacheServiceProvider.Instance;
    cache.AddItem(...);
    

    我同意这可能不是最简单的解决方案,但我的目标是在不牺牲代码去耦和灵活性的情况下利用ASP.NET缓存实现。

    我希望我理解你的问题。

        2
  •  1
  •   1800 INFORMATION    17 年前

    只要缓存仍然包含对数据的引用,数据就不会被垃圾收集。

    另外,不要使用单件。