c# - 如何在单例中使用作用域依赖注入(inject)

标签 c# .net-core dependency-injection

我有一个作用域服务(让它成为包含用户 IP 的 UserContext)。它服务我尝试注入(inject)另一个服务(我们称它们为 ProfileManagerLogerProvider)。

在我启动时的 Controller 中,我像这样添加了它们:

service
   .AddTransient(ILogerProvider, LogerProvider)()
   .AddSingleton<IProfileManager, ProfileManager)()
   .AddScoped<IUserContext, UserContext>()

LogerProvider 包含 UserContext 注入(inject):

class LogerProvider: ILogerProvider
{
   private readonly IUserContext _userContext;

   public LogerProvider(IUserContext userContext)
   {
      _userContext = userContext;
   }
}

ProfileManager 包含 LogerProvider 注入(inject):

class ProfileManager: IProfileManager
{
   private readonly ILogerProvider _logerProvider;

   public ProfileManager(ILogerProvider logerProvider)
   {
      _logerProvider = logerProvider;
   }
}

当我尝试运行我的程序时出现错误:

(Inner Exception #1) System.InvalidOperationException: Error while validating the service descriptor 'ServiceType: IProfileManager Lifetime: Singleton ImplementationType: IProfileManager': Cannot consume scoped service 'IUserContext' from singleton 'IProfileManager'.

我发现我可以改变 ProfileManager 的生命周期,让它变得短暂。但我需要像单例一样使用这项服务。那么一个问题:我如何实现依赖注入(inject)节省了服务的生命周期我在文本开头是如何输入的?

最佳答案

您需要手动创建一个范围并使用它,为此您需要将 IServiceProvider 注入(inject)到您的单例服务中,然后调用 IServiceCollection.CreateScope

public class ProfileManager : IProfileManager
{
    private readonly IServiceProvider _services;

    public ProfileManager(IServiceProvider services)
    {
        _services = services;
    }

    public void DoSomething()
    {
        using (var scope = _services.CreateScope())
        {
            var logger = scope.ServiceProvider.GetRequiredService<ILogerProvider>();
        }
    }
}

旁注:如果您发现自己一次又一次地重复这种模式,您可能需要重新考虑服务的生命周期和范围

关于c# - 如何在单例中使用作用域依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67631673/

相关文章:

macos - VSCode-如何在.Net Core 2.0+ API中管理用户 secret

c# - 从 Windsor 容器中删除或覆盖组件

c# - 如何修复 "Object reference not set to an instance of an object"?

java - 解耦与输入数据相关的对象构造

c# - 异步 sleep 循环

c# - Windows 窗体应用程序 : Displaying rows of content

c# - Oracle Date 列存储时间,但不显示它

.net-core - 使用 ClickOnce : how do I make it useable as a command-line app? 部署的 .net 核心控制台应用程序

c# - 最小起订量 IServiceProvider/IServiceScope

c# - .Net MVC Actionlink 在查询字符串中使用 %20 而不是 +