如何使用依赖项注入将对象传递给ViewModel

本文关键字:ViewModel 对象 何使用 依赖 注入 | 更新日期: 2023-09-27 18:27:57

我需要将一个对象从一个视图模型传递到另一个。在我当前的实现中,我按照这个例子创建了一个ProductVM的静态实例,然后从该实例访问它的属性。但从长远来看,传递静态实例似乎不是一个可靠的设计。

private static ProductVM _instance = new ProductVM();
public static ProductVMInstance { get { return _instance; } }

在研究提供静态视图模型实例的替代方案时,我发现构造函数注入是一种选择。

问题:

有人有关于如何实现对象传递的ctor注入的例子吗?(最好不要使用第三方框架)

产品虚拟机:(保存要发送的属性的视图模型)

    public ProductModel SelectedProduct { get; set; }

CustomerOrdersVM:(查看所选产品需要传递到的模型)

public class CustomerOrdersViewModel : IPageViewModel
{
    public CustomerOrdersViewModel()
    {                  
    }
}

如何使用依赖项注入将对象传递给ViewModel

Rowbear介绍了EventAggregators的情况。它们不可能在所有情况下都使用。

只有当目标ViewModel(及其对应的视图)已经实例化时,EventAggregator模式才有用,因为只有到那时ViewModel才会注册到要对其作出反应的事件。

这不适合在显示ViewModel/View之前也必须对其进行实例化/导航的情况。一个例子是智能手机应用程序,你点击一个产品,就会收到它的详细信息或类似的东西。

在这种情况下,您需要一个导航服务,在那里您可以将某个参数(productIdorderId等)传递给导航调用,如navigationService.Navigate("OrderDetails", orderId);,并让ViewModel实现某种INavigationAware接口,在ViewModel实现该接口的情况下,导航服务会调用该接口。

public class OrderDetailsViewModel : ViewModelBase, INavigationAware
{
    public async void OnNavigatedFrom(object parameter) 
    {
        var orderId = (int)parameter;
        var order = await orderRepository.GetOrderByIdAsync(orderId);
        // display your order in the ViewModel here
    }
}

导航服务附带了许多框架,最受企业应用程序欢迎的是Prism MVVM框架(最初由Microsoft开发)

您提供的示例链接中接受的答案实际上描述了构造函数注入。答案1和2都在技术上描述"构造函数注入"。为了在没有第三方框架的情况下实现构造函数注入,您基本上需要将SelectedProduct或ProductsVM实例传递给CustomerOrdersVM的构造函数。唯一剩下的是一个充当"注入器"的总体类或视图模型,它控制CustomerOrdersVM实例和ProductsVM实例的构造(或者至少有一个引用,它可以将该引用传递给CustomerOrders虚拟机的ctor):

public class MainViewModel : ViewModelBase
{
    public MainViewModel()
    {
        ProductsViewModel = new ProductsVM();
        OrdersViewModel = new CustomerOrdersVM(ProductsViewModel);
    }
    public CustomerOrdersVM OrdersViewModel { get; private set; }
    public ProductsVM ProductsViewModel { get; private set; }
}

我参与了一个MVVM(主要是)项目,该项目全程使用构造函数注入,而没有第三方注入程序。这是有意义的,因为我们有一个总体对象(从技术上讲,它充当主要的父视图模型和注入器),其中包含多个视图模型作为其属性。然而,它最终变得有些笨拙,因为一些视图模型在其构造函数中需要一个看似随机的其他视图模型。根据视图模型与模型或数据库/外部服务的分离程度,对视图模型进行单元测试也可能变得更加困难,因为您可能开始在视图模型中设置逻辑,要求使用生产数据完全构建依赖关系。

这让我问你。。。为什么您需要CustomerOrderVM中的SelectedProduct?是因为用户交互将在ProductsVM中设置SelectedProduct属性,而您的CustomerOrdersVM需要了解它吗?如果是这样的话,您是否考虑过实现EventAggregator模式?当我的团队中有人实现了这一点时,视图模型之间的信息传递就变得轻而易举了。视图模型将引用事件聚合器,并在构建时订阅事件。这样,当您的用户选择产品时,您的ProductsVM可以执行操作,并发布一个事件,您的CustomerOrdersVM可以订阅该事件并对其执行操作。