DI предоставляет возможность подпихивать что угодно :)
В принципе если действительно надо, то можно использовать абстрактный класс в роли токена, провайдить по нему конкретные реализации и использовать в потребители.
В самом Angular это сплошь и рядом, например ChangeDetectorRef, Injector, Renderer2, ViewContainerRef, TemplateRef, DomSanitizer, UrlHandlingStrategy и много других это абстракции, за которыми Angular прячет свои текущие реализации и они могут меняться в разных версиях, сохраняя интерфейс.
Но это не значит что такое требуется везде. Если вы пишете либу общего назначения, которая предоставляет свои сервисы, то еще уместно, а для конкретного сингла UserService это будет чересчур.
Все равно всегда можно скормить, если нужно, нижестоящему компоненту другой UserService подменив объект в инжекторе, di позволяет.