【发布时间】:2015-04-20 18:37:10
【问题描述】:
我的 WPF 应用程序使用 Caliburn.Micro 作为 MVVM 框架,使用实体框架作为数据访问技术。应用程序的目的是维护数据库。有多个Views 由菜单和结果数据网格组成。使用菜单控件,用户指定必须在结果数据网格中显示哪些 DB 数据。不同Views 中的一些ComboBoxes 在其ViewModels 中绑定到相同的属性List<EntityName>。(菜单有相同的项目可供选择)。当 ViewModel 初始化时,每个列表都从 DB 加载。我不想从数据库中为每个视图加载相同的列表,我想制作一次。为了实现这一点,我已经将这个List 属性移动到另一个类MenuLists 并使用PreloadLists() 方法从数据库中获取一次列表,然后使用Caliburn 的内置IoC 容器将这个类作为单例注入每个ViewModel。像这样:
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 构造函数中执行此操作,我将在第一个ViewModel 初始化中获得长时间的UI 冻结,因为MenuLists 的构造函数(具有昂贵的PreloadLists() DB-access 操作)将被调用。我不知道Views 会先打开什么,所以我不能从那里调用PreloadLists 方法。我需要在不冻结 UI 的情况下预加载我的列表一次。我该如何解决?也许会以某种方式延迟MenuLists 初始化?
【问题讨论】:
-
列表永远不会改变吗?也许在“PreloadLists”函数中添加一个“已加载”标志,并检查该标志,如果其为真,则返回,如果不加载列表。然后,您可以在应用程序启动时在另一个线程中调用该函数,或者作为闪屏操作的一部分(如果它已经加载,您也可以在每个函数中调用它而几乎没有影响)。你也可以有一个“ResetLists”函数来重置加载的标志并在列表发生变化时重新加载......
标签: c# mvvm dependency-injection singleton lazy-initialization