Что должно находиться в инфраструктурном слое в многослойном приложении?
==========================================================================

 Я прочитал много про различные слои и вроде бы всё понял. Но не понял суть инфраструктурного слоя.  
  

Мне казалось я уже понял, что он значит, сначала я думал, что там находятся классы, которые отвечают за функциональность, которая не является частью бизнес логики, но нужна для работы приложения.  

Также у меня была теория, что это классы, в которых задействованы сторонние библиотеки или компоненты из фреймворков.  
  

Но меня в ступор ввёл пример из книги 'Domain-Driven Design in PHP', вот:
```
namespace Ddd\Auth\Domain\Model;

interface SignUp {
    public function execute($aUsername, $aPassword);
}
```
Суть в том, что реализации этого интерфейса должны иметь разные механизмы хеширования пароля. В книге есть две реализации этого интерфейса, которые находятся в инфраструктурном слое, первая - это класс DefaultHashingSignUp, в нем используется встроенная в PHP функция password\_verify(). Вторая реализация - это класс Md5HashingSignUp, в нем используется встроенная в PHP функция md5() и "соль".  

В книге говорится, что эти классы являются "Infrastructure Services".  

Так вот, я не понимаю почему они находятся в инфраструктурном слое, в них же находится бизнес логика. Да, там есть встроенные в PHP методы, но ведь они не могут являться причиной? В различных Entites из Domain слоя тоже могут использовать встроенные функции, но ведь эти Entities из-за этого не находятся в инфраструктурном слое.  
  

Так почему бы не оставить DefaultHashingSignUp и Md5HashingSignUp в Domain слое? Зачем в этом случае нужна инверсия зависимости? Я вроде бы понимаю в чём суть инверсии зависимостей, её суть в том, что реализации должны подстраиваться под интерфейс, который объявлен в Domain слое, это как бы показывает, что Domain слой является центром приложения, что он не зависит от других слоёв. Но разве здесь инверсия уместна? Разве эти реализации не являются частью Domain слоя? Обязательно убирать их в другой слой? Почему они не могут остаться в Domain слое?  

Может быть они находятся в инфрастр. слое потому что реализаций несколько? А если было достаточно одной реализации, то есть хватило бы обычного класса SignUp, а для смены хеширования в нём бы использовался паттерн стратегия. Тогда можно было бы оставить его в Domain слое? (мне кажется это я ересь какую-то родил)  
  

Я(вроде бы)понимаю зачем нужна инверсия зависимостей в случае с Persistense слоем, классы из этого слоя не являются частью бизнес логики. Persistense слой - это же вроде бы как инструмент, ведь без возможности сохранять данные сложно реализовать приложение. То есть такой же инструмент как и язык программирования.  
  

Кароче, памагите, умаляю, а то я туплю, бомблю и устал. Мне кажется, что ответ очевиден, а я не всегда очевидное замечаю. Слишком много всего в голове крутится и не могу всё в кучу собрать. 

 Всё, что не важно для бизнес-логики, должно быть вне domain-слоя.  

Разве бизнесу важно, как будет выстроен хеш пароля? (Несомненно, зависит от бизнеса, но в 90% случаев нет).  

Спросите об этом доменного эксперта или хотя бы менеджера.   

Они могут даже не знать, что такое "хеш" в принципе.  
  

А интерфейс лежит в домене, потому что нужно как-то соединить это "неважно" с "нужно".   
  

Даже если бы была только одна реализация, ее в примере вынесли все равно.  
  

Можно ли положить в домене? Вы строите систему. Хотите, положите в доменный слой, хотите, вынесите в микросервис. Хотите, пишите на PHP, или на Go или на C++.  

Как решите Вы, так и делайте.   
  

Правильнее абстрагировать домен от всего лишнего. Всего, что не касается предметной области. Но вот только иногда (почти всегда) этого не удается сделать адекватно и следующий джун обязательно сделает что-то не так.   

Плюс к тому же, абстракциями можно задушиться, что потом не разберешься, что использовать.   
  

Есть моменты, которые будут меняться вне зависимости от вашей предметной области:  

обновления пакетов, уязвимости в безопасности при использовании чего-либо, новые быстрые реализации каких-либо модулей. В этом случае ваш бизнес-слой не должен быть подвержен изменениям. Но он четко должен знать, если вызовет реализацию этого интерфейса, то получит результат. Лишь это вы и должны гарантировать на бизнес слое.