我有一个带有控制器,服务和存储库的典型应用程序。因此,有2个项目:
WebAPI应该只了解Core提供的服务。在Core中,我具有返回DTO的公共类(服务),但是这些服务取决于我要标记为internal
的DbContext。我当然不能
错误CS0051可访问性不一致:参数类型 “ DevicesDbContext”比方法更难访问 'DeviceService.DeviceService(DevicesDbContext,IMapper)'
我正在使用EF Core和instead of own Repositories I use DbContext。我有仅在Core项目中必须使用的实体模型。您能建议我如何实现吗?
例如,我的模型是:
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)
{
}
..
}
我在DeviceService的构造函数中遇到了该错误。它不是duplicate,因为我知道该错误的含义以及解决方法。在这里,我询问了这种方法的设计或体系结构,因为我需要避免直接在WebAPI中使用模型和dbcontext
答案 0 :(得分:1)
如果您不想使用存储库来保护数据访问(通常仍返回实体,而不是DTO,则实体需要公开),那么真正的问题是: “为什么要避免在Web API中使用DbContext和实体?”
实体框架是一个框架。目的是促进数据访问,使您的代码更易于编写和理解。正如您选择使用.Net框架并通过选择EF来利用Linq,Generics等工具一样,您也应该尝试利用它提供的所有功能。
如果绝对必须将上下文和实体保留在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-仅引用DTO。
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
支持来保持我的数据访问层简单而紧凑,让消耗性服务决定如何获取所需的细节。用额外的服务边界来掩盖它会增加复杂性和低效率,因为这会导致代码复杂,功能非常相似,并且/或者浪费了内存/处理以返回不需要的数据。