Правильная реализация кеша в библиотеке классов для использования в приложении asp.net

StackOverflow https://stackoverflow.com/questions/156478

Вопрос

Я реализую кеш в библиотеке классов, которую использую в приложении asp.net.

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

MyCacheObject.Instance.MyDataCollection

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

MyOtherCacheObject.Instance.MyOtherDataCollection(indexkey)

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

Итак, мой вопрос: как лучше всего реализовать кеш для решения этой ситуации?Мне действительно не нравится такое огромное сложное решение, и я знаю, что в System.Web есть кеширование, но это кажется немного «неправильным», поскольку это всего лишь библиотека классов, или как вы думаете?

Это было полезно?

Решение

На мой взгляд, лучшим решением будут следующие характеристики:

  • Использует доступные службы кэширования, предоставляемые платформой, стараясь не писать свои собственные.

  • Не связывает вашу библиотеку классов с System.Web для обеспечения согласованности слоев.

  • Но если библиотека классов работает внутри приложения ASP.NET, решение не должно требовать включения другой реализации кэширования (например, блока приложения кэширования корпоративной библиотеки), что требует дополнительной настройки и настройки.

Итак, я бы использовал стратегию IoC, чтобы позволить библиотеке классов использовать различные реализации кэширования в зависимости от среды, в которой она работает.

Предположим, вы определяете свой абстрактный контракт кэширования как:

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

Вы можете предоставить реализацию на основе System.Web:

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

А затем опубликуйте эту реализацию как синглтон.Обратите внимание, что разница с вашим исходным подходом заключается в том, что синглтон — это просто ссылка на реализацию на основе службы кэша ASP.NET, а не на полный «объект кэша».

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

}

Вам придется инициализировать реализацию chaching либо путем выполнения ленивой инициализации, либо при запуске приложения (в global.asax.cs).

И каждый компонент домена сможет использовать опубликованную службу кэширования, не зная, что она реализована на основе System.Web.

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

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

Надеюсь, я правильно понял ваш вопрос.

Другие советы

Данные не будут собирать мусор, пока в кеше сохраняется ссылка на них.

Кроме того, никогда не используйте синглтоны.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top