Как хранить данные в кеше? - PullRequest
0 голосов
/ 07 сентября 2018

Я создал ViewComponent для отображения List<Product>, список оценен, взяты данные из службы REST API, это моя реализация класса:

public class ProductsViewComponent : ViewComponent
{
    private readonly HttpClient _client;

    public ProductsViewComponent(HttpClient client)
    {
        _client = client ?? throw new ArgumentNullException(nameof(client));
    }

    public async Task<IViewComponentResult> InvokeAsync(string date)
    {
       using (var response = await _client.GetAsync($"/"product/get_products/{date}"))
       {
           response.EnsureSuccessStatusCode();
           var products = await response.Content.ReadAsAsync<List<Product>>();
           return View(products);
       }
    }
}

Я загружаю Список в HTML-таблицу, которая доступна внутри папки Components: Views\Shared\Components\Products\Default.cshtml.

В каждом View, который должен отображать Products, который я сделал:

@await Component.InvokeAsync("Products", new { date = myDate })

REST API вызывается с использованием HttpClient, настроенного в Startup.cs следующим образом:

services.AddHttpClient<ProductsViewComponent>(c =>
{
    c.BaseAddress = new Uri('https://api.myservice.com');
});

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

Можно ли сохранить список в чем-то вроде кеша и предотвратить повторный вызов API, если дата равна предыдущей выбранной дате?

Я учусь ASP.NET Core, поэтому я не очень разбираюсь в этом аргументе.

Заранее спасибо за любую помощь.

Ответы [ 3 ]

0 голосов
/ 07 сентября 2018

Согласно документации Microsoft https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-2.1

вы можете использовать IMemoryCache для кэширования данных

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMemoryCache();

         services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseMvcWithDefaultRoute();
    }
}

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

Я настоятельно рекомендую вам ознакомиться с вышеуказанной документацией.

public class HomeController : Controller
{
    private IMemoryCache _cache;

    public HomeController(IMemoryCache memoryCache)
    {
        _cache = memoryCache;
    }

    public IActionResult CacheTryGetValueSet()
    {
       DateTime cacheEntry;

       // Look for cache key.
       if (!_cache.TryGetValue(CacheKeys.Entry, out cacheEntry))
       {
           // Key not in cache, so get data.
           cacheEntry = DateTime.Now;

           // Set cache options.
           var cacheEntryOptions = new MemoryCacheEntryOptions()
           // Keep in cache for this time, reset time if accessed.
                .SetSlidingExpiration(TimeSpan.FromSeconds(3));

           // Save data in cache.
        _cache.Set(CacheKeys.Entry, cacheEntry, cacheEntryOptions);
      }

      return View("Cache", cacheEntry);
   }

}

Обновление : CacheKeys.Entry - статический класс, в котором определены все ключи. (Просто стандарты кодирования). Пожалуйста, проверьте ссылку выше документации.

public static class CacheKeys
{
   public static string Entry { get { return "_Entry"; } }
   public static string CallbackEntry { get { return "_Callback"; } }
   public static string CallbackMessage { get { return "_CallbackMessage"; 
}    }
public static string Parent { get { return "_Parent"; } }
public static string Child { get { return "_Child"; } }
public static string DependentMessage { get { return "_DependentMessage"; 
} }
public static string DependentCTS { get { return "_DependentCTS"; } }
public static string Ticks { get { return "_Ticks"; } }
public static string CancelMsg { get { return "_CancelMsg"; } }
public static string CancelTokenSource { get { return "_CancelTokenSource"; } }}
0 голосов
/ 14 сентября 2018

Попробуйте

Cache["KeyName"] = VariableOrTable;  Cache.Insert("Key", VariableOrTable, null, 
Cache.NoAbsoluteExpiration, ts);
0 голосов
/ 07 сентября 2018

Вы можете использовать распределенный кеш и, таким образом, использовать Redis, например, с ConnectionMultiplexer.И поэтому для каждого вызова вы можете вызывать свой redis для кеша, который реализован благодаря интерфейсу вызова здесь 'IDistributedCache'. Вы можете найти много документации для реализации кеша и использовать его.: .Net framework
DotNet Core

Ваш контроллер X:

    [HttpGet]
    [Route("{itemId}")]
    public async Task<IHttpActionResult> GetItemById(int eventId, [FromUri]EventTabs tabId)
    {

        ServiceResponse<ItemDto> result = await _itemDispatcher.GetItemById(itemId);

        return WrapResponse(result);
    }

Ваш диспетчер, чтобы получить элемент по идентификатору, который используетRedis кеш (уже реализован)

 public class ItemDispatcher : ItemDispatcher
{

    private readonly IUnitOfWork _unitOfWork;
    private readonly IDistributedCache _distributedCache; // use interface of your implementation of redis cache

    private readonly int _cacheDuration;
    private readonly bool _isCacheEnabled;

    public EventDispatcher(IUnitOfWork unitOfWork, IDistributedCache distCache)
    {
        _unitOfWork = unitOfWork;

        _distributedCache = distCache; // init cache in constructor


        _cacheDuration = _configuration.Get<int>("cache.duration"); // duration of your cache
        _isCacheEnabled = _configuration.Get<bool>("cache.isEnable"); // if the cache is enable or not
    }



     public async Task<ServiceResponse<ItemDto>> GetItemById(int id)
    {
      // Add this for each Task call
          var cacheKey = string.Empty;

            if (_isCacheEnabled)
            {
                cacheKey = CacheUtils.GetCacheKey(CacheKeys.Item, id);
                itemDto cacheResult = await _distributedCache.Get<ItemDto>(cacheKey);

                if (cacheResult != null)
                    return new ServiceResponse<Item>(cacheResult);
            }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...