Правильная реализация кеша в библиотеке классов для использования в приложении asp.net
-
03-07-2019 - |
Вопрос
Я реализую кеш в библиотеке классов, которую использую в приложении 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, не жертвуя при этом развязкой кода и гибкостью.
Надеюсь, я правильно понял ваш вопрос.
Другие советы
Данные не будут собирать мусор, пока в кеше сохраняется ссылка на них.
Кроме того, никогда не используйте синглтоны.