我仍然犹豫是否要使用视图模型而不是视图模型



我是否使用自动映射器或手动映射,这没有任何作用。

ReleaseViewModel 的所有数据都必须排在 Release 中的第一个,因为它是用它填充在数据访问层中的。 我的模型90%都是这样的。为什么要复制所有内容的开销?

那么KISS原理和过度工程呢?

当然,每个工具都可以完成适当的任务,但是我经常在SO上读到,在MVC中不使用ViewModels是不行 asp.net。

在哪里划线?当视图模型与我的模型区别为 50%、75% 或 99% 时,我应该使用 ViewModels 吗?

我有一个模型发布:

 public class Release
    {      
        public int Id { get; set; }       
        public string Name { get; set; }
        public string Author { get; set; }
        public DateTime CreatedAt { get; set; }
        public int FailedTestsCount { get; set; }
        public int SucceededTestsCount { get; set; }
        public int SumTestsCount
        {
            get
            {
                return SucceededTestsCount + FailedTestsCount;
            }
        }
        public int SumTestingTime { get; set; }
    }
视图模型

发布视图模型:

public class ReleaseViewModel
{
    [HiddenInput(DisplayValue = false)]
    public int Id { get; set; }
    [Required(ErrorMessage = "Name must not be empty.")]
    [StringLength(30, ErrorMessage = "Enter max. 30 chars for a name.")]
    [Remote("ReleaseExists", "Release", ErrorMessage = "This name already exists.")]
    public string Name { get; set; }    
    public string Author { get; set; }    
    public DateTime CreatedAt { get; set; }    
    public int FailedTestsCount { get; set; }    
    public int SucceededTestsCount { get; set; }    
    public int SumTestsCount 
    {
        get
        {
            return SucceededTestsCount + FailedTestsCount;
        }
    }
    public int SumTestingTime { get; set; }
}

ViewModel是用于视图的东西。 大多数情况下,它类似于实体模型。但并非总是如此。

看看你的例子。在ViewModel 中,您有 Remote 属性和一些验证属性。因此,您添加此远程名称检查是为了为用户提供更好的用户体验。它特定于视图。

您需要视图模型的另一种方案是用于涉及多个模型的屏幕。例如:您有一个User实体和一个Project实体,并且您希望提供一个屏幕,可以在其中将项目添加到用户。因此,在这种情况下,您可以创建一个视图模型来处理它

public class ProjectToUserVM
{
  public int UserId { set;get;}
  public string UserName { set;get;}  // i want to display only name of user!
  public int ProjectID { set;get;}
  public IEnumerable<SelectListItem> Projects { set;get}
}

不要对所有模型实体使用 ViewModels。当您的视图真正需要它时创建它。 我在某些视图中直接使用我的模型实体对象,有时没有创建视图模型,因为它们完全相同。例如:国家/州/城市(查找表数据。没有添加/编辑)

为什么要复制所有内容的开销?

首先,你可能认为我在复制代码,但事实是你不是,如果你这样做,你有一个严重的设计问题

我发现有一个原则,当你

不遵循它时,它确实是万恶之源:SRP(单一责任原则)。

也许

是因为您还没有发现问题,或者也许,您已经找到了,并且您只是修补了代码。域对象的责任与向用户呈现数据的责任完全不同。

MVC 中的模型应该是一个类,表示视图需要呈现的所有数据,仅此而已。您需要使用域中的数据填充此模型。(或在 CQRS 体系结构中,从查询服务)

如果遵循 CQRS 体系结构(至少是基础知识,无需实现事件源,也无需使用服务总线即可将命令与查询分开),这将更清楚,查询对象的责任与命令对象(域中的操作)完全不同

我认为您误解了KISS原则,虽然它谈到了过度设计代码或YAGNI,但这并不意味着您必须重用应用程序中的所有内容。

相信我,

我学到了这一点 不好 =(,唯一应该重用的代码是基础设施代码,在谈论域代码时,最好始终遵循 SRP

我的 ViewModels 只需包装一个模型,并在 90% 的时间内委托给它。 只有当我需要针对特定视图用例更改有关模型行为的某些内容时,它们才有自己的行为。 将 VM 放在那里确实可以更轻松地添加仅用于显示目的的行为,特别是如果该行为会干扰持久性模型(例如,添加不希望持久化的属性)。

还值得注意的是,很有可能使用 Castle 或 SpringFramework.net 等 IoC 工具来动态生成默认转发行为,从而减少需要手动编写的代码量。 这大大降低了"复制成本",因此它并不像最初看起来那么糟糕。

我支持Shyju所说的一切,尤其是关于"当你需要它时"的部分。

如果您有一个非常简单的项目,其中您的 EntityModel 类与 ViewModel 类位于同一库中,您可能不需要单独的 ViewModel dto,并且可以放弃它们。我不认为任何聪明的人会告诉你"你做错了,因为你正在为视图模型使用实体类,dumass。我们不知道应用程序的上下文是什么。这可能完全适合您的情况。

我们中的一些人在非 Web 程序集中定义 EntityModels——只是一个编译成 DLL 的普通类库——用于大型项目。在这种情况下,我们通常只需要将特殊属性应用于视图,例如示例问题中的 RemoteAttribute 和 HiddenInputAttribute。但是,要在不使用单独的视图模型 dto 层的情况下执行此操作意味着我们必须添加对 System.Web.Mvc.dll 到 EntityModel 库的引用,而实际上该库与 Web 无关

请记住,当您在 Web 项目中重用 EntityModel 类(即将它们用作存储模型和表示模型)时,您将在项目的 Web 方面和项目的业务方面之间创建更紧密的耦合。如果你能因为成本/预算、时间、目标受众、范围或其他限制而证明这一点,那就去做吧,忽略你的批评者,因为他们没有看到像你那么大的情况。

如果您的 Release 类实现了 INotifyPropertyChanged 以及视图所需的所有其他内容(验证、命令等),那么您不必使用视图模型。 但如果不是...

相关内容

  • 没有找到相关文章

最新更新