Web API 分层架构 - 最佳实践

Web API tiered architecture - best practices

为了改进我的项目架构,我最近几天看到了几个 Web - API 项目示例。

我目前有:
Project.WebApi - 主要由控制器、脚本等组成
Project.DAL - 包含我的模型和存储库 class。
还有一些不相关的部门。

我的问题是:
1. 我看到很少有项目将模型和存储库 class 一起放在 DAL 库中,而其他项目则将它们分开。到底哪个更好,见仁见智?
2. 我的控制器接收 JObjects,因此我发现自己在我的控制器 中不止一次将 JObjects 转换为数据对象 ,这对我来说似乎是错误的。我想为我的每个模型创建自定义 JSON convert class。对于这样的 class(以及其他类似的 classes),是否可以创建一个名为 Common 或 core 的库?或者我误解了这个概念?
代码示例:

var taskId = (int)taskstatus["Id"];
var status = (string)taskstatus["Status"];
var userCreated = (int)taskstatus["UserCreated"];
if (taskId == 0 || status == null || userCreated == 0)
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
var newTask = new Task{
Id = taskId,
userCreated = userCreated
...
}

在我看来,将上面的所有代码留在控制器中是不对的,控制器应该更简单、更简洁。
3.仓库如下:

public class Context : DbContext
{
public DbSet<Tasks> Tasks { get; set; }
public DbSet<Projects> Projects { get; set; }
...

就这么简单。再次回到我的控制器——我发现自己在我的控制器中做了很多复杂的查询,我又一次觉得这是错误的。我认为控制器不应该处理此类查询。处理复杂查询的最佳做法是什么?也许我应该创建一个新的 class 来继承我的上下文 class,覆盖它的一些父 class 并在那里进行复杂的查询?

  1. 我会把它放在同一个项目中,因为那些 类 与数据库非常相关(但这也可能取决于您的设计)。

  2. 我会将对象转换代码放在您的控制器之外。而且我推荐使用转换库,比如Automapper, or look for a pattern that is designed to do that. E.g.: Design pattern for converting one model to another model

  3. 我会在存储库中放入复杂的查询。简单的 linq 查询(比如只包含一个 orderby 的查询)可以保留在控制器中。
  1. 就我个人而言,我会将您的模型放在单独的项目中。将来可以很容易地与其他项目共享这些内容,而无需随身携带 DAL 标签。

  2. 同意 Joanvo 的观点,AutoMapper 是必经之路。此外,拥有一个单独的项目,其中包含用于将 JObjects 映射到 model/poco 对象的 AutoMapper 配置文件将是明智之举。你希望你的控制器尽可能愚蠢。在网络 api 项目中,我在控制器上工作几乎总是在那里接受请求,然后将其传递给业务层(在您的情况下为映射层)。

  3. 你不应该在你的控制器中放置任何查询....这就是你的 DAL 的用途。