如何在单例中使用作用域依赖注入

Cla*_*olz 3 c# dependency-injection .net-core

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

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

service
   .AddTransient(ILogerProvider, LogerProvider)()
   .AddSingleton<IProfileManager, ProfileManager)()
   .AddScoped<IUserContext, UserContext>()
Run Code Online (Sandbox Code Playgroud)

LogerProvider包含UserContext注入:

class LogerProvider: ILogerProvider
{
   private readonly IUserContext _userContext;

   public LogerProvider(IUserContext userContext)
   {
      _userContext = userContext;
   }
}
Run Code Online (Sandbox Code Playgroud)

ProfileManager包含LogerProvider注入:

class ProfileManager: IProfileManager
{
   private readonly ILogerProvider _logerProvider;

   public ProfileManager(ILogerProvider logerProvider)
   {
      _logerProvider = logerProvider;
   }
}
Run Code Online (Sandbox Code Playgroud)

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

(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'.
Run Code Online (Sandbox Code Playgroud)

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

Min*_*ipe 5

您需要手动创建一个作用域并使用它,为此,您需要将其注入IServiceProvider到您的单例服务中,然后调用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>();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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