1. BarService как бизнес-сервис не должен знать о другом бизнес-сервисе, т.е. о FooService. Если приходит понимание, что в BarService нужно вызывать метод из FooService, значит Ваш FooService должен стать компонентом более низкого уровня, чем бизнес-сервис. Например, FooManager (вспомните всякие ***Manager из ASP.NET Identity). Тогда этот FooManager можно будет использовать не только в BarService, но в каком-нибудь другом ***Service. Архитектурно будет выглядеть так: наверху ***Service (бизнес-логика), ниже - ***Manager (тоже бизнес-логика), еще ниже - ***Repository (а это уже DAL).
2. Да, бывает необходимость расширить Generic-репозиторий конкретным репозиторием. Но тут надо
очень хорошо подумать, почему мы это делаем. Возможно, мы пытаемся на конкретный репозиторий навесить часть бизнес-логики? Если так, то это уже не конкретный репозиторий и даже не компонент уровня DAL - это компонент уровня бизнес-логики. Ну да ладно, допустим, мы поняли, что нам-таки нужен IFooRepository. Я сталкивался с таким решением этой задачи: в IUnitOfWork добавляется новое свойство:
public IFooRepository FooRepository {get; }
И все. Инициализация выполняется внутри экземпляра UnitOfWork, например, так:
public IFooRepository FooRepository {get; } = new FooRepository();
а "наружу" нам доступен FooRepository:
_uow.FooRepository.CallSomeMethod(...);
В итоге в BarService Ваш код будет выглядеть примерно так:
public void CreateBar(BarDTO bar)
{
// Insert Bar entity
_uow.FooRepository.CreateFoo(new FooDTO());
_uow.Commit();
}
Но повторюсь. В Вашем примере у меня есть подозрения, что метод CreateFoo должен принадлежать не FooRepository, а какому-то компоненту уровня бизнес-логики (но в иерархии он не является бизнес-сервисом). Например, FooManager или FooCreator какой-нибудь (который отвечает только за создание объекта). Помните принцип SRP.