【问题标题】:Putting logic in ViewModel get'ers将逻辑放入 ViewModel get'ers
【发布时间】:2010-04-26 09:43:18
【问题描述】:

您如何看待将 Get-logic 放入 ViewModel 的 getter 中?比如:

public class DummyViewModel
{
    public int Id { get; set; }

    private DummyObject myObject;

    public DummyObject MyObject
    {
        get
        {
            if (MyObject == null)
            {
                DummyRepository repo = new DummyRepository();
                myObject = repo.Get(Id);
            }
            return myObject;
        }
    }

}

这是不好的做法,还是完全没问题?我发现我的控制器通过在那里执行所有 get-logic 变得非常臃肿,但我真的不知道应该把它放在哪里......

我这样做的原因是,我可以将 ViewModel 传递给不同类型的视图,并且只会根据请求的属性执行必要的 DB 查找。

【问题讨论】:

    标签: c# asp.net-mvc model-view-controller


    【解决方案1】:

    将逻辑放入 VM 中的 getter 并没有错 - VM 的作用是将数据呈现给视图,它应该尽可能准备好“查看”(视图不应该也必须这样做)很多(如果有的话)在显示之前对数据进行整形)。

    例如,我在我的 VM 中使用名为 GetAvailableClients 的属性,这将是视图绑定到的属性之一。该特定 getter 的工作是过滤数据 - IOW 提供从完整列表(也保存在 VM 中)中选择的一组精简数据,这些数据通常会使用 LINQ 进行过滤,这意味着我已经放置了一些自定义逻辑在吸气剂中。

    我不喜欢你的其他方法,如果属性没有被填充,它会转到存储库并获取数据本身。对我来说这是一个禁忌,该物业完全违反了single responsibility的原则,让物业承担过多责任。更不用说,一旦您开始将该属性绑定到 UI,您的应用程序就会开始挂起,因为您的属性 getter 已被触发并且它已决定调用数据库或网络服务,更糟糕的是,调用已经在 UI 线程上完成......它变得丑陋了。

    【讨论】:

    • 很好的回应!所以你认为我可以有一个私有方法 GetDummyObjects(),然后使用我的 getter 来做一个 return GetDummyObjects().Where(some lambda-expression) ?我没听错吗?
    • 是的,这与我会做的类似,但我会进一步拆分。 GetDummyObjects() 调用将作为 VM 的构造函数或加载的一部分完成,或者由监督控制器完成,然后传递结果。 Where(lambda) 将在 getter 中。
    • 只是为了进一步阐述,在 getter 中有 Where(lambda) 的一个原因是因为您的主列表可能是对象的同质列表 - 它可能是订单列表,其中还包含一些客户信息。无需对存储库进行多次调用(从时间上看,这可能是一项昂贵的任务),您可以通过从 VM 拥有的订单列表中过滤/选择信息来在视图中显示客户端列表。这仍然符合 VM 的任务——它将数据呈现给视图。
    【解决方案2】:

    就我个人而言,我的视图模型中不包含任何逻辑——它们几乎是愚蠢的 DTO。我当然不会让 VM 负责通过存储库自行加载。

    【讨论】:

      【解决方案3】:

      你的问题很笼统,但我会尽量回答。

      我不喜欢这些东西:

      1) 可测试性。您的财产正在创建存储库,您将如何模拟您的存储库并对其进行测试?

      2) 延迟加载。延迟加载是潜在的性能损失,视图模型不应该这样做。如果将视图模型绑定到包含数百个条目的网格会发生什么?

      3) 暴露身份。您的 Id 属性(我假设它是实体的主键值)有一个设置器。您要在视图中显示此 ID 吗?如果不是,请摆脱它,如果是,请删除二传手。 setter 意味着视图必须执行某种业务功能来查找正确的值,这会破坏 SoC。

      【讨论】:

      • 这是我想要采用的方法,使我的 ViewModel 保持简单和“愚蠢”。因此,在您的方法中,您将在控制器中进行所有数据检索,填充模型并返回它的观点? (我猜这是“正确”的做法)
      • 我没有控制器(但这是另一个讨论)。我的 ViewModel 将具有引用您的 DummyObject 的 DataSource 属性,因此 viewmodel 对存储库是无知的。如果此 ViewModel 被另一个 ViewModel 以主/细节关系使用,则“主” ViewModel 将具有用于初始化细节 ViewModel 数据源的提供者/存储库引用。所以“愚蠢”取决于你操作的级别,但请记住在任何级别都保持 SOLID 原则:-)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-10
      • 2013-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多