Размышляя о разделении интересов и распределении обязанностей, вы должны точно указать, от чего зависит ваш артефакт. Это может показаться немного очевидным, но это немного глубже.
Учитывая ваш (2) пример:
В ClientService (домен) я должен внедрить UserService и из него вызвать UserRepository или я могу внедрить UserRepository непосредственно в ClientService?
Вам, вероятно, следует сначала спросить себя, от каких возможностей зависит ваша клиентская служба?
Если его (ClientService) заботит возможность найти пользователя по информации, которой он (ClientService) в настоящее время обладает, он, вероятно, должен получить UserRepository напрямую и иметь возможность самостоятельно найти пользователя.
Если ему (ClientService) нужен пользователь, но он не обладает информацией, необходимой для поиска пользователя (эта информация в настоящее время находится на уровне приложения), возможно, ClientService должен получить объект домена пользователя напрямую, с хранилище используется прямо с уровня приложения.
Если ему (ClientService) требуется какая-то относящаяся к домену функциональность от UserService как часть его работы, то в этом случае UserService может быть непосредственно введен в ClientService.
Другое возможное обсуждение по этой теме может заключаться в том, действительно ли вам нужны все эти доменные службы, если вам лучше будет называть объекты / агрегаты, богатые правилами, прямо из уровня приложений, это может упростить ваш общий дизайн, шаблоны внедрения и границы.
Кроме того, часто вам может понадобиться ввести фабрики для вашего артефакта, а не непосредственно созданные экземпляры.
Можно сделать еще одно замечание относительно:
Но я также думаю, что мне не следует внедрять репозиторий другой сущности, потому что часто методы репозитория имеют правило в службе, которое должно вызываться ранее.
Это может быть свидетельством некоторой путаницы внутри вашего домена. Роль репозитория должна быть примерно такой же, как «поиск сущности вашего домена из вселенной возможных сущностей». В этом смысле UserRepository позволяет вам находить пользователей от пользователей, существующих в вашем юниверсе, поэтому он должен быть довольно изолированной операцией и не зависеть от служб или других объектов. Если пользователь существует, он должен быть «доступным для поиска» (и постоянным, поскольку он идет в обе стороны) из UserRepository.
В этом случае вам не нужно беспокоиться о «внедрении UserRepository в ClientService» с догматической точки зрения. Если для операции в вашей клиентской службе необходимо найти и использовать пользовательскую сущность, вам следует сделать это. Что вас может беспокоить, так это то, что ваши сущности / агрегаты хорошо спроектированы или если у вас есть какие-то неуместные обязанности, которые могут вызывать это «чувство» «я не должен вводить это в это».