8

我有一个带有需要服务的构造函数的视图模型。我正在使用 GalaSoft 的 MvvmLight,它使用服务定位器将视图连接到视图模型。

SimpleIOC 可以很好地处理向 viewmodels 构造函数提供服务,但我需要用来自数据源的数据填充我的 viewmodel。我的 Viewmodel 看起来像这样:-

    public class MainPageViewModel : ViewModelBase
{
    private readonly GroupService _groupService;
    private readonly GroupFactory _groupFactory;
    private readonly ObservableCollection<GroupVM> _groupVms = new ObservableCollection<GroupVM>();


    public MainPageViewModel(Domain.Services.GroupService groupService, VMFactories.GroupFactory groupFactory)
    {
        _groupService = groupService;
        _groupFactory = groupFactory;
    }

    public async Task Init()
    {
        var groups = await _groupService.LoadGroups();
        foreach (var group in groups)
        {
            GroupVms.Add(_groupFactory.Create(group));
        }
    }

    public ObservableCollection<GroupVM> GroupVms { get { return _groupVms; } }
}

不知何故,init 方法需要被称为等待,但我不知道如何最好地做到这一点?我可以想到三个选项:-

  1. 我只是在构造函数上调用 Init,但不等待它(我知道那是非常糟糕的做法)
  2. 我在 ViewModelLocator 对象上调用 Init,但由于我无法返回任务,我再次无法等待 init
  3. 在视图加载时,我将 DataContext 转换为某种 IAsyncViewmodel 并等待 init 方法。

我在以前的 Windows 8 商店项目中使用过选项 3,但感觉不对。任何建议将不胜感激!

谢谢

罗斯

4

2 回答 2

8

我很好奇为什么您认为不等待异步调用是一种不好的做法。在我看来,只要你知道这意味着什么,调用将在后台执行并且可能随时返回就不错了。

通常我所做的是我在构造函数中调用 async 方法来创建设计时数据,并且我不等待它。我只负责在需要更新绑定的地方引发 PropertyChanged 和 CollectionChanged 事件,这样就可以了。

干杯劳伦特

于 2012-12-17T14:29:25.830 回答
1

我不像以前那样熟悉 MvvmLight,但我尝试过以async各种方式处理构造函数。

选项 (1) 具有错误处理复杂性。选项 (3) 强制InitAsync可访问。

我更喜欢async工厂方法(例如,选项(2),它DataContext会一直保留null到 VM 初始化完成),但听起来好像ViewModelLocator不起作用。因此(目前)您必须在async不使用 IoC 的工厂和不理想的其他选项之一(1 或 3)之间进行选择。

就个人而言,我会抛弃 IoC 来进行 VM/View 绑定(无论如何我从不使用 IoC;我的视图取决于我的 VM)并使用async工厂方法。但是,如果您想留在 IoC,其他选项是完全可行的。对于虚拟机,我认为选项(1)会比选项(3)稍微好一点,如果你的方法中总是有一个顶级try/ 。catchInitAsync

于 2012-12-16T21:12:50.240 回答