在哪里将实体/模型转换为MVVM中的视图模型

本文关键字:模型 MVVM 视图 转换 实体 在哪里 | 更新日期: 2023-09-27 18:11:29

在MVC中非常简单:

客户端发出请求,控制器要求业务逻辑做一些花哨的事情,业务逻辑要求存储库返回一些数据,然后存储库返回数据,业务逻辑负责将数据从实体转换为视图模型,视图模型返回给客户端。

在MVVM中,我几乎迷路了,因为视图模型本身负责向业务逻辑发出请求,没有像控制器那样的"中间层"。我可以在业务逻辑项目中实现映射器,但由于视图模型负责向业务逻辑请求数据,因此它将创建循环引用。

那么我应该在哪里让这个"奇迹"发生呢?

在哪里将实体/模型转换为MVVM中的视图模型

我将尝试用一个简单的例子给出一些背景。

请注意,下面所有的代码都是概念性的,在这里写,而不是在vs中。

将ViewModel视为模型的包装器。你的模型是由一个属性公开的,所以你可以从视图绑定到它或它的属性。

你的ViewModel:

  public class SomeEntityViewModel : NotificationObject
  {
       private SomeEntity _someEntity;
       public  SomeEntity SomeEntity
       {
           get{ return _someEntity;}
           set
           {
               _someEntity = value;
               RaisePropertyChanged("SomeEntity");
           }  
       }  
  } 

现在假设您向服务器发送了一个请求并等待响应。

让我们也假设你有一个更高的对象(像父视图模型)启动你的VM:

  public class SomeEntityContainerViewModel : NotificationObject
  {
      public ObservableCollection<SomeEntityViewModel> Items;
      public void async OnRequestNewEntity() 
      {
         SomeEntity newEntity = await _someEntityService.CreateSomeEntityAsync();
         var vm = new SomeEntityViewModel{ SomeEntity = newEntity};
         Items.add(vm);
      }
  }

你的SomeEntityContainerView的SomeEntityContainerViewModel是DataContext:

  <UserControl>
      <Button Command="{Binding RequestNewEntityCommand}" />
      <ItemsControl ItemsSource="{Binding Items}" />
  </UserControl>

SomeEntityViewModel为DataContext的SomeEntityView:

    <UserControl>
        <TextBlock Text="{Binding SomeEntity.Name}" />
    </UserControl>

在最简单的设计中:

你的模型需要"哑",只有数据。你的ViewModel是最接近控制器的,它将处理逻辑,它是将包装(不是转换)你的模型在视图模型中的组件。

在上面的例子中,我们有一个更高的对象:父对象ViewModel,它初始化我们的ViewModel。

这相当于一个控制器的作用域,它在DOM中有其他嵌套的控制器。

基于mvvm-light参考,我假设这里是WPF应用程序。如果您在第一段提到您的业务逻辑(我将从这里称之为服务)负责转换为视图模型。我认为服务不应该知道视图。因此,在这种情况下,控制器(或由控制器或模型绑定器调用的映射器)将处理映射。

在MVVM(我的意见在这里,而试图为你画一个比较)ViewModel的行为很像控制器,因为它去,得到模型,映射和绑定到一个可观察对象。然后,它也是绑定到视图的模型(mvc中经常使用的视图模型)。

所以我认为这里的技巧是移动映射应该发生的地方。服务不应该知道视图的任何信息。它们没有与视图耦合,这是一件好事。

在MVVM中,您所指的"业务层"是"模型"-实际上,视图模型之后的任何内容都被认为是"模型"的一部分。然而,在我所做的任何工作中,我总是将这个模型拆分为n层,通常带有一个控制器样式的类,该类使用服务从数据存储库检索数据实体。

在哪里将实体/模型转换为视图模型?

严格来说,你不需要。视图模型可以包含实体(即VM有一个ObservableCollection),或者视图模型可以包装实体(在列表控件中很有用,你可能需要显示选项或按行执行操作)。

对实体的MVC方法比MVVM更脏,你最终得到的是一个更丰富的商业模型,而不是一个漂亮的精益实体。在MVVM中,"丰富度"主要是由视图模型分离和处理的,并且您尝试保持数据实体尽可能简单(是的,您可以在实体中包含验证之类的东西,但您应该只在必要时这样做,其他时候验证应该在VM或模型中的某个地方进行)。

你的问题问反了。视图模型表示用户与应用程序交互背后的逻辑,所以真正的问题应该是"当用户交互请求实体和模型时,视图模型如何获取它们?"答案是:"使用依赖注入框架,例如Ninject"。这允许你将实体范围扩展到WPF应用程序中的页面,MVC或WCF应用程序中的web请求,任何外部控制台实用程序中的单例,或测试框架中的模拟对象……所有这些都不需要你的视图模型知道或关心这些实体或提供它们的服务是如何被创建或在内部工作的。