我在.NET Core 2中尝试使用web api,我试着像这里的例子一样干净地分离问题:https://msdn.microsoft.com/en-us/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时,它变得更加明显,如“任务”等。
有一个更好的方法吗?
我还没有看到DTO界面,如果您有不同的具有共同属性的客户端,您可以使用它。我看到的问题是您在实体(您的Business Objects)和DTO(您从客户端发送/接收的内容)之间混淆。
通常,作为客户端的Controller不会知道存储库层。这应该是服务层的知识。
如果您只有一个使用Entity Framework的数据访问层,并且您不打算将其放在一边,我建议您根本不要使用Repository层,因为它已经实现了Repository(DbContext
)和Unit Of Work (DbSet
)。
标准的SOLID架构看起来像这样(每个都是一个单独的项目):
string
,int
等)或DTO,并返回DTO请注意,只有域/业务层实际上看到代表您的数据库的实体。