Definitivamente, puede dedicar mucho tiempo a la ingeniería excesiva de este problema.
Para los idiomas con implementaciones de registro canónico, simplemente cree una instancia del registrador canónico directamente en cada clase.
Para los idiomas sin una implementación canónica, intente encontrar un marco de fachada de registro y apegarse a él. slf4j es una buena opción en Java.
Personalmente prefiero apegarme a una única implementación de registro concreta y enviar todo a syslog. Todas las buenas herramientas de análisis de registros son capaces de combinar registros de sysout de múltiples servidores de aplicaciones en un informe completo.
Cuando una firma de función incluye uno o dos servicios de dependencia, así como algunos argumentos "reales", coloco las dependencias al final:
int calculateFooBarSum(int foo, int bar, IntegerSummationService svc)
Como mis sistemas tienden a tener solo cinco o menos servicios, siempre me aseguro de que los servicios se incluyan en el mismo orden en todas las firmas de funciones. El orden alfabético es tan bueno como cualquiera. (Aparte: mantener este enfoque metodológico para el manejo de mutex también reducirá sus posibilidades de desarrollar puntos muertos).
Si se encuentra inyectando más de una docena de dependencias en su aplicación, entonces el sistema probablemente deba dividirse en subsistemas separados (¿me atrevo a decir microservicios?).