asp.net-mvc - 构建 View 模型的最佳方法是什么?

标签 asp.net-mvc entity-framework domain-driven-design viewmodel repository-pattern

我正在使用带有 Entity Framework 的 asp.net mvc 并开始学习 DDD。我正在从事包含调查的项目。这是我的域模型:

public class Survey
{
    public int? SurveyID { get; set; }
    public string Name { get; set; }
    public decimal MinAcceptanceScore { get; set; }
    public int UserFailsCount { get; set; }

    public IEnumerable<SurveyQuestion> Questions { get; set; }
    public IEnumerable<Prize> Prizes { get; set; }
    public IEnumerable<SurveyAttempt> UserAttempts { get; set; }
}

我需要针对不同 View 进行不同部分的调查,因此我创建了不同的 ViewModel:
    public class ShortSurveyViewModel
    {
        public int? SurveyID { get; set; }
        public string Name { get; set; }
        public int UserFailsCount { get; set; }
        public IEnumerable<SurveyAttempt> UserAttempts { get; set; }
    }

    public class ShortSurveyWithPrizesViewModel
    {
        public int? SurveyID { get; set; }
        public string Name { get; set; }
        public int UserFailsCount { get; set; }
        public IEnumerable<SurveyAttempt> UserAttempts { get; set; }
        public IEnumerable<Prize> Prizes { get; set; }
    }

    public class SurveyEditViewModel
    {
        public int? SurveyID { get; set; }
        public string Name { get; set; }
        public decimal MinAcceptanceScore { get; set; }
        public int UserFailsCount { get; set; }

        public IEnumerable<SurveyQuestion> Questions { get; set; }
        public IEnumerable<Prize> Prizes { get; set; }
    }

如果我希望我的调查存储库获取适当 View 模型所需的信息,那么构建我的架构的最佳方式是什么?

我看到的不同解决方案:
  • Repository 可以将 IQueryable 返回到 SurveyService 并且 service 可以返回适当的 View 模型,但我犹豫这样做是否正确,因为我认为 View 模型应该在 UI 中创建,而不是在服务层中创建。
  • 在我的领域层中创建三个适当的类。但是现在域将依赖于表示,并且每个新 View 都应该创建新的域类。
  • 检索完整的域对象并仅映射特定 View 所需的属性。这不好,因为在我的示例中,问题只需要一种表示形式,并且可能是大量收集。
  • 最佳答案

    领域驱动设计:

  • 您应该有一个返回聚合根的存储库 - 在您的情况下为 Survey以及所有没有父级就无法存在的关系Survey
  • 此存储库将始终加载整个 Survey类并根据您的要求只是一些关系(真正教条的 DDD 总是会加载整个聚合,但这对于无状态 Web 来说不是一个好方法)。
  • 您的应用程序层( Controller )将向存储库请求 Survey以及选定的关系和填充 View 模型。

  • 洋葱架构:
  • 您将创建一些暴露 IQueryable<Survey> 的存储库- 更糟糕的是,您将使用带有 CRUD 接口(interface)的通用存储库
  • 您将创建一些服务调用存储库并将 Linq-to-entities 投影构建到您的 DTO 中并将它们返回到应用程序层( Controller )
  • 怎么办?您可以直接使用这些 DTO,也可以使用另一组对象作为您的 View 模型以及一些与 UI 相关的属性等。显然有问题...

  • 简单的架构:
  • 您将使用注入(inject)的 IDbSet<Survey>直接在您的 Controller 中作为存储库
  • 您将直接在 Controller 中进行 Linq 到实体的投影以填充 View 模型

  • 没有最好的办法。它始终与您的目标和期望有关。对于小型应用程序,您可以毫无问题地使用简单的架构。

    领域驱动设计更复杂。 DDD 中的主要概念是领域实体、值对象及其组合。域实体封装了数据和在这些数据上执行的逻辑。 DDD 不适用于部分数据或 DTO - 当您的域实体没有任何逻辑时,您做错了(称为贫血模型)。 DDD 中的服务不是应用层和存储库之间的中介。它用于处理与单个域实体无关的业务逻辑(因此不能封装在域实体中)。存储库是从存储中实现聚合并将它们持久保存在存储中所需的基础架构代码。应用程序逻辑( Controller )可以与域实体、服务和基础设施代码交互。

    我不喜欢洋葱架构。

    关于asp.net-mvc - 构建 View 模型的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15531846/

    相关文章:

    c# - ASP MVC 允许静态 html 文件

    c# - 从 ASP.NET MVC 应用程序发送传真

    c# - 条件 IQueryable 选择 (MVC .NET EF)

    c# - 增加或更新 Entity Framework 的数量

    php - Composer 建议的内部包方法

    mvvm - 领域模型对 View 模型的依赖有多糟糕?

    c# - .NET MVC 自定义 View 引擎布局

    c# - System.Web.MVC.ModelState 没有 IsValid 的定义

    asp.net - 在运行时控制 ASP.NET Web API 中的 [JsonIgnore]

    domain-driven-design - 定时任务应该放哪一层?