К какому слою относится 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.  
  

Как решить эти проблемы? 

 Привет! Многое зависит от деталей и количества абстракций. Попытаюсь ответить как это должно выглядеть в самом общем случае. UserRepository использует напрямую доступ к базе данных (это может быть raw sql, какая-то ORM, неважно). Поэтому логично, чтобы он находился в Data Access Layer. Он поэтому так и называется, потому что на практике их может быть несколько: SqlDataAccessLayer, MongoDbDataAccessLayer и т.д. Также если мы говорим про ООП, то интерфейс IUserRepository должен хранится именно там, где планируется его использование. В нашем случае это BLL, он же Domain Layer. Не всегда удаётся придерживаться этого правила с интерфейсом, но к этому нужно стремиться.  

По поводу того, что должен возвращать UserRepository: на самом деле без разницы. Смотря от ситуации мы можем либо возвращать просто контейнер c необходимыми данными (DTO), либо полноценного User'a. Если говорить о зависимостях, то главное понимать, что в общем случае наш Domain Layer не должен иметь зависимостей от каких-то других слоёв. А вот остальные части нашего проекта (например, DAL) могут использовать Domain Layer. 

 как правило 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.  
  

Я описал абстрактный пример, он может варироваться от платформы и размера приложения 

```
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 / пакета