商业逻辑层中模型封装的问题



我有一个带有控制器,服务,存储库的典型应用程序。因此,有两个项目:

  • ASP.NET带有控制器的Core WebAPI
  • 所有业务逻辑的核心

WebAPI应仅了解来自Core的服务。在核心中,我有返回DTO的公共类(服务(,但是这些服务取决于我要标记为internal的DBContext。当然我不能

错误CS0051不一致可访问性:参数类型 " deskicesdbcontext"不及方法易于访问 'deviceservice.deviceservice(deskicesdbcontext,imapper('

我正在使用EF Core,而不是自己使用DBContext的存储库。我的实体模型仅在核心项目中使用。您能建议您如何实现吗?

例如,我的模型是:

internal class Device
{ 
   public int Id {get;set;}
}

dbContext:

internal class DevicesDbContext : DbContext
{
   public DbSet<Device> Devices {get;set;}
}

服务:

public class DeviceService : IDeviceService
{
   public DeviceService(DevicesDbContext dbContext, IMapper mapper)
   { 
   }
   ..
}

我在devanceService的构造函数中遇到了这个错误。这不是重复的,因为我知道该错误的含义以及如何解决。在这里,我询问了这种方法的设计或体系结构,因为我需要避免直接在WebAPI中使用模型和DBContext

如果您不想使用存储库来守卫数据访问(通常仍然返回实体,而不是DTO,因此实体需要公开(,那么真正的问题是:"为什么要避免在Web API中使用DBContext&amp;的实体?"

实体框架是一个框架。目的是促进数据访问,以使您的代码更易于编写和易于理解。正如您选择使用.NET框架并利用Linq,Generics等。通过Chossing Ef,您应该寻求利用其提供的所有内容。

如果您绝对必须将上下文和实体远离API组件参考,或者想集中涉及Web API和另一组MVC控制器之间的业务逻辑,那么您正在考虑构建贫血API。在这种情况下:

services.dll-参考dbcontext,实体..

public interface ISomethingService
{
  IEnumerable<SomeDto> GetSome(/*params*/);
}
public class SomethingService : ISomethingService
{
    public SomethingService(SomeDbContext context) 
    { // Init stuff. 
    }
    IEnumerable<SomeDto> ISomethingService.GetSome()
    {
       // Get some stuff and return DTOs.
    }
}

Web API DLL-仅引用DTOS。

public class SomeAPI : ISomethingService
{
    private ISomethingService Service { get; set; }
    public SomeAPI(ISomethingService service)
    {
        Service = service;
    }
    public IEnumerable<SomeDto> GetSome()
    {
        return Service.GetSome();
    }
}

API是贫血的,因为它只是将请求传递给通用服务并转发响应。API不需要实现相同的接口,它可以简单地接受对服务的引用并消耗它,并通过任何参数以获取将会传递的DTO。

这种方法的缺点是,要修改您要在API和服务层之间进行翻转的服务,而不是在API中工作。我不喜欢使用这样的方法,因为API和这种方法通常需要考虑诸如过滤,分页等的细节。因此,我想利用EF提供的出色LINQ功能。我还利用EF的IQueryable支持很大程度上使我的数据访问层保持简单,紧凑,让消费服务决定如何获取所需的细节。用额外的服务边界掩盖此功能会增加复杂性和效率低下,因为它会导致复杂的代码,许多非常相似的功能和/或浪费的内存/处理以返回不需要的数据。

最新更新