Проблема с инкапсуляцией модели на уровне бизнес-логики - PullRequest
0 голосов
/ 23 мая 2019

У меня типичное приложение с контроллерами, сервисами, репозиториями. Итак, есть 2 проекта:

  • ASP.NET Core WebAPI с контроллерами
  • Ядро со всей бизнес-логикой

WebAPI должен знать только об услугах от Core. В ядре у меня есть публичные классы (сервисы), которые возвращают DTO, но эти сервисы зависят от DbContext, который я хочу пометить как internal. Конечно, я не могу

Ошибка CS0051 Несоответствующая доступность: тип параметра DevicesDbContext менее доступен, чем метод 'DeviceService.DeviceService (DevicesDbContext, 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)
   { 
   }
   ..
}

Я получил эту ошибку в конструкторе DeviceService. Это не дубликат , потому что я знаю, что означает эта ошибка и как ее исправить. Здесь я спросил о дизайне или архитектуре этого подхода, потому что мне нужно избегать непосредственного использования моделей и dbcontext в WebAPI

1 Ответ

0 голосов
/ 23 мая 2019

Если вы не хотите использовать хранилища для защиты доступа к данным (которые обычно по-прежнему возвращают сущности, а не DTO, поэтому сущности должны быть открытыми), тогда реальный вопрос: «Почему вы хотите избежать использования DbContext & Entities в вашем веб-API?»

Entity Framework - это фреймворк. Его цель - облегчить доступ к данным, чтобы ваш код был легче писать и понимать. Точно так же, как вы решили использовать .Net Framework и использовать такие вещи, как Linq, Generics и т. Д., Выбирая 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.
    }
}

DLL API Web - только ссылки на 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 и уровнем Services, вместо того, чтобы просто работать внутри API. Я не одобряю использование таких подходов, потому что API-интерфейсам и тому подобному часто приходится учитывать такие детали, как фильтрация, разбиение на страницы и т. Д., Поэтому я хочу использовать превосходные возможности LINQ, которые предлагает EF. Я также активно использую поддержку IQueryable EF, чтобы сделать мой уровень доступа к данным простым и компактным, позволяя потребляющим службам решать, как получить необходимую информацию. Маскирование этого с помощью дополнительной границы обслуживания добавляет сложности и неэффективности, так как это приводит либо к сложному коду, множеству очень похожих функций и / или трате памяти / обработки для возврата данных, которые не нужны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...