Я вообще одно время практиковал доменные сервисы, т.е. за контроллерами два слоя сервисов, за которыми уже слой базы данных. Первый слой это бизнес слой, второй доменный. В доменом слое происходят операции специфичные для конкретных сущностей, в бизнес слое - какие то интеграционные операции, которые связывают между собой доменные. В каких то случаях это можно успешно выразить через один сервисный слой и богатые сущности, которые сами знают что с ними можно делать, но это получения далеко не всегда
Я и сейчас так делаю. Почему перестали и что стали использовать вместо этого?
Просто эта идея с 2-мя слоями "сервисов" зарождается сама собой, когда оказывается, что тебе нужно производить какую-то доменную операцию в конечном счете из разных контроллеров. А т.к. 1-й уровень сервиса работает с ДТО, то во-первых инжектить их друг в друга - сразу начинает попахивать (и чревато круговыми зависимостями). Во-вторых, даже если это сделать, ты получишь ДТО, а тебе нужен домен. В итоге 2 слоя "сервисов" получаются сами собой. Просто иначе сложно переиспользовать код. Только я бы 2-й слой не стал называть слоем "сервисов".
Я бы и первый слой, честно говоря, не стал. Но так уж сложилось почему-то.. Мы сами себя ограничиваем, и вместо множества разных классов делаем какой-то UserService и пытаемся туда притянуть за уши все операции с сущностью User. Хотя по сути UserService - это часть контроллера, если так разобраться. И его методы обычно маппятся 1-к-1 на методы контроллера, принимают и возвращают DTO и т.д. А все бизнес-операции должны быть где-то в нижележащих слоях в более специализированных классах без суффикса Service (и вообще без какого-либо суффикса, хотя чаще всего какой-то приходится придумывать, типа UserManager. Мне это не нравится, но не понятно, как по-другому.).