К какому слою относится Repository и как возвращать Business object?

Язык не важен. Например, у меня есть база данных с таблицей User.
В моей программе есть Data Access Layer (DAL) и Business Logic Layer (BLL).
В DAL для таблицы User у меня написан класс сущности UserEntity{username, secondname, age ...}, которая, соответственно и отражает в себе данные отдельного поля таблицы.
В своем BLL у меня есть объект User{fullname, age}, который получается путем превращения UserEntity -> User, т.е. происходит mapping.

Также у меня есть UserRepository, который инкапсулирует работу с хранилищем и возвращает данные. Вот здесь у меня и возникли вопросы:
1) Что должен возвращать UserRepository : UserEntity или User?
2) В каком слое должен находиться UserRepository DAL или BLL

Если по логике, то DLL вообще не должен знать про BLL, тем более про его объекты. Но выходить, что если я хочу, чтобы
репозиторий возвращал User, то получается DLL подвязан на BLL. То есть, если репозиторий находится в DAL, то он никак не должен возвращать объекты BLL. Но во многих статьях я видел, что наоборот, пишут - repository возвращает Business objects.

Как решить эти проблемы?
  • Вопрос задан
  • 649 просмотров
Пригласить эксперта
Ответы на вопрос 4
@maltsever
Привет! Многое зависит от деталей и количества абстракций. Попытаюсь ответить как это должно выглядеть в самом общем случае. UserRepository использует напрямую доступ к базе данных (это может быть raw sql, какая-то ORM, неважно). Поэтому логично, чтобы он находился в Data Access Layer. Он поэтому так и называется, потому что на практике их может быть несколько: SqlDataAccessLayer, MongoDbDataAccessLayer и т.д. Также если мы говорим про ООП, то интерфейс IUserRepository должен хранится именно там, где планируется его использование. В нашем случае это BLL, он же Domain Layer. Не всегда удаётся придерживаться этого правила с интерфейсом, но к этому нужно стремиться.
По поводу того, что должен возвращать UserRepository: на самом деле без разницы. Смотря от ситуации мы можем либо возвращать просто контейнер c необходимыми данными (DTO), либо полноценного User'a. Если говорить о зависимостях, то главное понимать, что в общем случае наш Domain Layer не должен иметь зависимостей от каких-то других слоёв. А вот остальные части нашего проекта (например, DAL) могут использовать Domain Layer.
Ответ написан
@dmitriylanets
как правило Repository - уровень инфраструктуры а не домена, с доменом они связанны интерфейсами.
например доменная сущность (по сути это BLL):
Domains/User/User
Domains/UserCollection
Domains/User/RepositoryInterface (возвращает User, UserCollection)

Инфраструктура:
Infrastructure/User/Repository (реализует RepositoryInterface, работает с бд, использует DAL, mapping)

ну и Application
контроллеры, GUI , views
Ответ написан
Я обычно делаю это следующим образом.

Есть проект Domain в котором описаны общие интерфейсы для BLL и View(REST, SOAP, CLI, Desktop и т.д.). Тут есть некий интерфейс IUserService, который работает с User.
Есть проект со всей бизнес логикой, который реализует IUserService в UserService. Этот UserService ходит в DAL, откуда получает UserEntity и преобразовавает её в User. Кроме этого здесь происходят валиадации, отправка нотификаций, т.е. все что нужно бизнес логике. Отдельно есть проект DAL, который уже ходит в базу и возвращает UserEntity через UserRepository.

View при этом знает только o существования Domain проекта, а все реализации пробрасываются через IoC.

Я описал абстрактный пример, он может варироваться от платформы и размера приложения
Ответ написан
@AlexHell
class User {Id, Name, Age}

class UserRepository
{
 User GetUserById(long Id)
  {
  string[] data = {select from Users where id = Id}
  return new User() {Id = Id, Name = data[0], Age = data[1] };
  }

  void PutUser(User)
  {
    {insert into Users}
  }
}


Зачем вам UserEntity? Если у вас доменный объект User - везде его и передавайте, и Repo олжен его же вертать при чтении из БД и его же принимать чтоб сохранять в БД.

Если вопрос в EntityFramework (и иже с ними ORM) с обязательным отнаследованием от базового Entity класса - ну сделайте маппинг опять же внутри UserRepo и не отдавайте вообще никогда вовне UserEntity, всмысле как private class например чисто для namespace / пакета
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы
OS33 Нижний Новгород
от 120 000 до 150 000 руб.
от 80 000 до 100 000 руб.
АстроСофт-МИР Красноярск
от 45 000 до 75 000 руб.