0

Мое приложение WPF использует Caliburn.Micro как инфраструктуру MVVM, Entity Framework в качестве технологии доступа к данным. Цель приложения - поддерживать базу данных. Есть несколько Views, которые состоят из меню и результата данных. С помощью элементов управления меню пользователь указывает, какие данные БД должны отображаться в результатах datagrid. Некоторые из ComboBox es в разных Views привязаны к тем же свойствам List<EntityName> в их ViewModels. (Меню имеют одинаковые элементы на выбор). Каждый из этих списков загружается из БД при инициализации ViewModel. Я не хочу загружать одинаковые списки из БД для каждого представления, я хочу сделать это один раз. Для достижения этой цели я переместил этот объект в другой класс MenuLists с помощью метода PreloadLists() для получения списков из БД один раз, затем инжектировал этот класс как singleton для каждого ViewModel с помощью встроенного контейнера IoC Caliburn. Как это:Инициализация однопользовательского режима с использованием контейнера IoC в приложении MVVM

IoC конфигурации контейнера:

container.PerRequest<KitchenOneViewModel>(); 
container.PerRequest<KitchenTwoViewModel>(); 
container.Singleton<IMenuLists, MenuLists>(); 

MenuLists класса:

public class MenuLists : IMenuLists 
{ 

    public List<Meat> MeatLst { get; set; } 
    public List<Fish> FishLst { get; set; } 

    public void PreloadLists() 
    { 
     using (var db = new DBEntities()) 
     { 
      MeatLst = db.Meat.OrderBy(x => x.MeatName).ToList(); 
      FishLst = db.Fish.OrderBy(x => x.FishName).ToList(); 
     } 
    } 
} 

впрыскиванием в ViewModel:

public KitchenOneViewModel(IMenuLists menuLists) 
    { 
     _menuLists = menuLists; 
    } 

Проблема заключается в том, что мне нужно позвонить MenuLists.PreloadLists() как-то , но если я сделаю это в контенте MenuLists, я буду g et long UI замерзает вначале инициализация ViewModel, потому что будет вызван конструктор MenuLists (с дорогостоящей операцией DB-доступа) . Я не знаю, что из View s будет открыто первым, поэтому я не могу позвонить PreloadLists оттуда. Мне нужно предварительно загрузить мои списки один раз без замораживания пользовательского интерфейса. Как я могу это решить? Может быть, задержка MenuLists инициализация каким-то образом?

+1

Не меняется ли этот список? Возможно, добавьте «загруженный» флаг в функцию «PreloadLists» и отметьте флаг, если он верен, верните, если не загрузите списки. Затем вы можете вызвать функцию внутри другого потока при запуске приложения или как часть операций с spash-screen (вы можете также вызвать его в каждой функции с небольшим количеством импульсов, если оно уже загружено). У вас также может быть функция «ResetLists», которая сбрасывает флаг загрузки и перезагружает списки, если они меняются ... –

ответ

1

Либо лениво загрузить каждый список в отдельности, чтобы сократить время инициализации, что-то вроде:

//only initialized when it's used 
private static Lazy<List<Meat>> meatList 
    = new Lazy<List<Meat>>(
      () => 
      { 
       //load single list here 
      } 
    ); 
public List<Meat> MeatList { get{ return meanList.Value; } } 

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

В качестве альтернативы вы можете рассмотреть возможность инициализации async, если вам не нужно блокировать.

+1

'Lazy' именно то, что я хотел. Благодаря! – AsValeO