我应该在Web API中使用DTO接口吗?

卡斯滕·格林

我正在尝试在.NET Core 2中使用Web api,在这里尝试像下面的示例中那样将关注点清晰地分开:https : //msdn.microsoft.com/zh-cn/magazine/mt703433.aspx

我想知道的一件事是:使用存储库接口设置/获取数据时,数据类型是否也应该是接口?

示例(减少以强调问题):

public class ProjectController : Controller
{
    IProjectRepository _repo;

    [HttpGet]
    public IProject GetProject([FromRoute] string key)
    {
        return _repo.GetProject(key);
    }
}


public interface IProjectRepository
{
    IProject GetProject(string key);
}


// Implementation based on Entity Framework
public class EFProjectRepository : IProjectRepository
{
    private SomeEfContext _context;

    public IProject GetProject(string key)
    {
        return _context.Projects.SingleOrDefault(p => p.Key == key);
    }
}


public interface IProject
{
    string Key { get; set; }
    string Name { get; set; }
}


// EF specific implementation
public class Project : IProject
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public string Key { get; set; }
    public string Name { get; set; }
}

我这样做的原因是,如果我不这样做,那么EF实现特定字段Id将“渗入”控制器,这是我所不希望的。就像我说的那样,此示例非常简单,存在此Id字段的原因-当将示例与诸如“任务”等相关的DTO扩展在一起时,它变得更加明显。

有一个更好的方法吗?

卡米洛·特雷文托(Camilo Terevinto)

我还没有看到DTO接口,但是如果您拥有具有相同属性的其他客户端,则可以使用它。我看到的问题是,您在实体(您的业务对象)和DTO(您从客户端发送/接收的内容)之间混在一起。
通常,作为客户端的Controller不会知道存储库层。这应该是服务层的知识。
如果您只有一个使用Entity Framework的数据访问层,并且您不打算将其放在一边,那么我建议您完全不要使用存储库层,因为它已经实现了存储库(DbContext)和工作单元(DbSet)。

标准的SOLID体系结构如下所示(每个都是独立的项目):

  • 项目核心
    • 所有人可见
    • 不包含任何参考
    • 包含您的DTO和帮助程序类
  • Project.DataAccess
    • 对域可见
    • 包含您的EF素材
  • 项目域
    • 仅在配置DI时对Web可见
    • 参考核心
    • 接收并返回DTO
    • 这实际上是您的业务逻辑所在
  • 项目抽象
    • 对网络和域可见
    • 包含服务的接口,这些接口在Domain中实现
  • 项目测试
    • 参考领域和核心
    • 包含您的测试
  • Project.Web
    • 参考域,抽象和核心
    • 包含您的实际Web API
    • 使用依赖注入来调用域的服务。
    • 接收原语(string,,int等)或DTO,然后返回DTO

注意,只有域/业务层才实际看到代表数据库的实体。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章