使用 Entity Framework 6 在 n 层设计中保存新记录的示例流程是否正确

Is the sample flow correct for saving a new record in an n-layered design using Entity Framework 6

我一直在尝试使用 Entity Framework 开发带有 WinForms 应用程序的 N 层设计。

下面的示例流程是否适用于使用 Entity Framework 在 n 层设计中保存新记录?

  1. 表示层

    A) UI 执行光屏输入数据验证。然后 UI 转换 查看模型到 DTO 并将其传递到应用层。

  2. 应用层

    A) 应用层将DTO发送给领域层中的领域模型

  3. 领域层

    A) 之前验证传入的 DTO 值是否符合业务规则 创建域模型软件请求实体的新实例。

    B) 如果所有值都经过验证,则创建域的新实例 模型软件请求实体。

    C) 退出到return控制到应用层

  4. 应用层

    A) 调用基础设施层软件请求 存储库并传入新的域模型 SoftwareRequest 实体 由领域模型提供

  5. 基础架构层数据访问

    A) SoftwareRequest 存储库从应用层接收新的领域模型 SoftwareRequest 实体。

    B) 添加新的域模型软件请求实体到 Entity Framework DBContext - context.SoftwareRequests.Add(NewDomainModelEntity)

    C) 保存新实体 - context.SaveChanges()

    D) 退出到 return 控制权回到应用层

  6. 应用层

    A) 将保存操作的结果转换为 DTO

    B) 退出到 return 控制返回到 UI,DTO 包含结果 添加新的软件请求

  7. UI

    A) 将收到的 DTO 转换为视图模型

    B) 在屏幕上显示视图模型数据,显示添加新软件请求的结果

-------- 以下信息于 2016 年 2 月 22 日在太平洋标准时间 6:49am 添加 ----------

依赖性摘要:

表示层 - 引用应用层来发出请求 - 仅出于使用描述 DTO 的接口的目的引用域层,这些 DTO 将从 UI 发送或从应用层

接收

应用层 - 引用描述 DTO 的域层接口。还使用领域模型实体的接口定义,因此它可以将实体响应从基础设施层转换为 DTO,后者被 returned 到 UI。对基础设施层数据访问的引用也在这里,因此在域层针对规则和值验证了所涉及的域模型实体之后,可以访问存储库以执行 CRUD 操作。

领域层 - 没有对上方或下方任何层的引用。没有来自任何层的依赖注入服务。这不包括涉及基础结构存储库 CRUD 的任务。所有请求(例如规则验证)都会收到 DTO,其中包含执行请求的域任务所需的所有必要信息。

基础架构层数据访问 - 引用域层接口,描述用于在存储库中执行 Entity Framework 操作(即 CRUD 操作)的域模型实体。还参考了域层以定义在基础设施层数据访问中实现的存储库接口。该层不使用 DTO。该层通常使用领域模型实体响应应用层。应用层将所有域模型实体响应(即 IEnumerable)转换为发送回 UI 的 DTO。

根据您的描述,我怀疑 DTO 类型是在 Domain 层中声明的。这并不是它们真正属于的地方,因为 DTO 可能会随着客户端的变化而变化,我们不希望每次客户端发展时都修改域。此外,DTO 可以包含用例级字段,例如 confirmPassword 域不感兴趣。

另一件事是,应用层应该控制业务交易,而不仅仅是域的门面。

以下是我的调整方式:

  1. 应用层

    A) 应用层将 DTO 映射到新实体,通过调用其构造函数或如果构造复杂则调用工厂

  2. 领域层

    A) 在实体构造函数或工厂中,验证实体初始化的值(不可为空性、值范围、相关参数等)

    B) 退出到return控制到应用层

...

  1. 基础架构层数据访问

    A) SoftwareRequest 存储库从应用层接收新的域模型 SoftwareRequest 实体。

    B) 添加新的域模型软件请求实体到 Entity Framework DBContext - context.SoftwareRequests.Add(NewDomainModelEntity)

    C) 退出到return控制权回到应用层

  2. 应用层

    A) 保存新实体 - context.SaveChanges()

    B) 将保存操作的结果转换为DTO

请注意,当您将业务事务控制从基础架构层移至应用层时,您可能必须引入新的抽象(通常是工作单元)以从 Entity Framework 的 DbContext.

编辑:一个例子来说明这一点

/* Application layer */

public class SoftwareRequestDTO
{
    public string Name { get; set; }
    // your other SoftwareRequest data here
}

public class SoftwareRequestApplicationService
{
    // constructor etc...

    public void CreateSoftwareRequest(SoftwareRequestDTO dto)
    {
        using (var transaction = new BusinessTransaction()) // UoW or whatever - can also be constructor injected into the service
        {
            var softwareRequest = new SoftwareRequest(dto.Name);
            _softwareRequestRepository.Add(softwareRequest);
            transaction.Complete();
        }
    }
}

/* Domain layer */

public class SoftwareRequest
{
    public SoftwareRequest(string name)
    {
        // validation/guard clause
        if (name == null)
        {
            throw new DomainException("SoftwareRequest name cannot be null");
        }
        // your assignments here
    }
}