Как правильно загрузить тяжелую коллекцию? - PullRequest
0 голосов
/ 03 сентября 2018

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

Что я пытаюсь сделать

В моем приложении после выполнения входа в систему пользователь будет перенаправлен на Dashboard Home View. Dashboard - это место, которое содержит все функции для пользователя. У Dashboard Controller есть и другие Views, такие как:

  • Главная
  • Анализ
  • Производительность

Теперь каждый View должен отображать пользователю Table, который содержит список Products, внизу этого Table находится содержимое View.

Проблема

Первая проблема: это код избыточности Table, который я решил создать _PartialView, который содержит html из Table, который содержит продукты для отображения. Исходя из c # + WPF я использовал ту же логику UserControl, так что это хорошее решение для меня.

Вторая проблема: продукты для отображения внутри Table, эти продукты загружаются с API, теперь, как я уже говорил, эти записи должны всегда отображаться в продуктах Table (которые доступны в разных View с использованием _PartialView). Представьте, что каждый раз, когда пользователь нажимает на элемент Dashboard (который загружает Dashboard View), Dashboard Controller будет вызывать этот метод:

 public async Task<List<Products>> GetProducts(string date)
 {
    var client = new RestClient(Url);

    var request = new RestRequest("product/get_products/{date}", Method.GET);
    request.AddUrlSegment("date", date);

    var cancellationTokenSource = new CancellationTokenSource();
    var response = await client.ExecuteTaskAsync(request, cancellationTokenSource.Token);

    List<Products> products =  JsonConvert.DeserializeObject<List<Product>>(response.Content);
    return products;
 }

Для меня это не очень хорошая практика, потому что каждый раз _PartialView будет вызывать этот метод и перезагружать данные, поэтому мне нужно как-то хранить эти данные (временное хранилище). Как я могу сохранить эти записи в сеансе пользователя без перезагрузки каждый раз, когда вызывается _PartialView?

Между тем у меня есть некоторые сомнения по поводу метода API: Должен ли я поместить все вызовы API в папку Service? Папка Repository? Или Controller папка?

Папка дерево

View <- Folder
    Dashboard <- Folder
        Home
        Analysis 
        Performance
       _ProductsTable

View Home, Analysis, Performance загружает _ProductsTable следующим образом:

@await Html.PartialAsync("_LeftSidebar")

1 Ответ

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

Используйте вид компонентов. По сути, они являются автономными функциональными модулями, которые возвращают представления, которые вы можете встраивать в другие представления, без необходимости просмотра какого-либо из них основного представления или действия.

Сначала создайте директорию вызова ViewComponents. Внутри добавьте новый класс, например ProductsViewComponent. Тогда вам нужно что-то вроде:

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);
       }
    }
}

Затем создайте представление, Views\Shared\Components\Products\Default.cshtml. Внутри добавьте HTML, чтобы отобразить список продуктов. Наконец, там, где вы хотите, чтобы появилась таблица продуктов, добавьте:

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

В приведенном выше коде используется HttpClient, а не RestClient, поскольку, честно говоря, на данный момент совершенно не нужно иметь отдельную библиотеку для выполнения HTTP-вызовов. HttpClient является встроенным и расширен в функциональности в Core, чтобы упростить это, например, метод ReadAsAsync, использованный выше, который прозрачно десериализует ваш ответ JSON в аргумент универсального типа. Кроме того, теперь у вас есть такие вещи, как IHttpClientFactory, что обеспечивает правильную область действия HttpClient экземпляров. В результате приведенный выше код также предполагает добавление к вашему Startup.cs чего-то вроде следующего:

services.AddHttpClient<ProductsViewComponent>(c =>
{
    c.BaseAddress = new Uri('https://api.myservice.com');
    // add default headers and such if you need them
});

Затем вы также можете использовать интеграцию Polly для настройки автоматических повторных попыток, автоматических выключателей и т. Д., Что позволяет обрабатывать все виды сценариев API, такие как временно недоступные, ограничения скорости и т. Д. См. Полную документацию для обоих IHttpClientFactory и его интеграция Полли для получения дополнительной информации.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...