【问题标题】:Passing parameters to a service that already has dependency injection将参数传递给已经具有依赖注入的服务
【发布时间】:2025-12-28 17:30:14
【问题描述】:

我有一个带有以下构造函数的服务

        public TokenService(UserManager<IdentityUser> userManager, ApplicationDbContext dbContext)
        {
            _userManager = userManager;
            _dbContext = dbContext;
        }

在 Startup.cs 我已经注册了服务:

     services.AddScoped<TokenService>();

我想在构造函数中添加一个字符串参数,并将字符串传递给我在 Startup.cs 中注册服务的服务

我知道您可以通过在注册过程中创建新实例来传递参数,但我不知道在手动执行时如何传递 UserManger 和 ApplicationDbContext 对象。

如果我这样做:

services.AddScoped<>(_ => new TokenService(null , null, "secret");

它不适用于其他服务的依赖注入。

作为一种解决方法,我在 Program.cs 中添加了带有方法的字符串,但想删除它。

【问题讨论】:

  • 现在不能写出正确的答案,但我有一个模糊的记忆,你可以告诉 DI 如何构造一些东西......这个,或者类似的东西:services.addSingleton&lt;TokenService&gt;(_ =&gt; new TokenService(null, null, "hello"));
  • 我必须从 Singleton 更改为 Scoped 才能使用 UserManager,您给我的这段代码可以编译,但是当我尝试使用该服务时 UserManager 为空。
  • 啊,是的,因为你现在明确地用 null 构造它。接受的答案是正确的。

标签: c# asp.net-core


【解决方案1】:

通常,当您想为也需要注入依赖项的东西提供参数时,您最终会创建一个工厂。但是在这种情况下,由于在注册过程中参数是已知的,您可以轻松地直接修复此注册工厂方法:

services.AddSingleton(serviceProvider => new TokenService(serviceProvider.GetRequiredService<UserManager<IdentityUser>>(), serviceProvider.GetRequiredService<ApplicationDbContext>(), "hello"));

在您的 cmets 中,您声明这不能是单例,这与工厂方法无关,就像注册瞬态一样容易,例如:

services.AddTransient(serviceProvider => new TokenService(serviceProvider.GetRequiredService<UserManager<IdentityUser>>() , serviceProvider.GetRequiredService<ApplicationDbContext>(), "hello"));

希望对你有帮助

【讨论】:

  • 是的,这行得通,起初我想知道出了什么问题,但它应该这样读: services.AddTransient(serviceProvider => new TokenService(serviceProvider.GetRequiredService>() , serviceProvider.GetRequiredService (), "你好"));