Хз ответил уже кто или нет, но у методов AddTransient/Scoped/Singleton есть перегрузки с одном параметром <T1> и перегрузки с двумя <T1, T2>
Так вот, <T1> == <T1, T1> - сокращение для двух параметров, когда тип совпадает
А теперь пояснение:
1) Первый параметр это тип, по которому ты сервис будешь запрашивать в конструкторе или из IServiceProvider
Это может быть интерфейс, абстрактный и/или базовый класс для второго параметра, или даже T1 == T2
2) Второй параметр это тип, который будет реально создан. Его конструктор будет вызван механизмом DI.
Так что реальное использование будет выглядеть так
AddTransient<IUserService, UserService>();
Или даже может быть
AddTransient<UserService>()
Который аналог
AddTransient<UserService, UserService>()
И, я думаю, уже понятно, что в конструкторе ты в этом случае ничего не получишь, запросив IUserService