简体   繁体   English

.NET Core 6 将数据库上下文注入 Singleton 服务

[英].NET Core 6 inject databasecontext to Singleton Service

I have a problem when try to use database context in one Singleton Service in my app.尝试在我的应用程序的一个 Singleton 服务中使用数据库上下文时遇到问题。

App.cs应用程序.cs

...
var service = builder.Services;
service.AddDbContext<MyDBContext>(options => options.UseSqlite(connectionString));
service.AddSingleton<MyMonitorManager>();
...

MyDBContext.cs MyDBContext.cs

public class MyDBContext : ApiAuthorizationDbContext<ApplicationUser>
  {
    public DroneDBContext(...): base(options, operationalStoreOptions){}
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){}
    protected override void OnModelCreating(ModelBuilder modelBuilder){}
  }

MyMonitorManager.cs MyMonitorManager.cs

public class MyMonitorManager {
   private readonly MyDBContext _databaseManager;
   ...
}

There are errors:有错误:

Cannot consume scoped service 'MyController.MyDBContext' from singleton 'MyController.Service.MyMonitorManager'.无法使用 singleton 'MyController.Service.MyMonitorManager' 中的范围服务 'MyController.MyDBContext'。

I try to search here and think about use like this:我尝试在这里搜索并考虑这样的使用:

MyDBContext dbContext = new MyDBContext();
service.AddSingleton(new MyMonitorManager(dbContext));

But not sure this is how I should do in .NET 6但不确定这是我在 .NET 6 中应该怎么做

You can use IServiceScopeFactory in your singleton class to create a new scope, and then get a db context reference from that:您可以在 singleton class 中使用 IServiceScopeFactory 来创建新的 scope,然后从中获取数据库上下文引用:

public class MyMonitorManager {
    private readonly IServiceScopeFactory _scopeFactory;
 
     public MyMonitorManager(IServiceScopeFactory _scopeFactory)
     {
        _scopeFactory = scopeFactory;
     }
 
     public SomeMethod()
     {
        using (var scope = _scopeFactory.CreateScope())
        {
            var db = scope.ServiceProvider.GetRequiredService<MyDBContext>();
            ...
        }
     }
}

You can't inject directly scoped service into singleton, you have follwoing options:您不能将作用域服务直接注入 singleton,您有以下选项:

  1. Register database context with different lifetime, though in general case it is not the best option:注册具有不同生命周期的数据库上下文,尽管在一般情况下它不是最佳选择:
service.AddDbContext<MyDBContext>(options => options.UseSqlite(connectionString), ServiceLifetime.Transient);
  1. Inject IServiceScopeFactory to create scope and resolve context when needed the singleton service:注入IServiceScopeFactory以创建 scope 并在需要 singleton 服务时解析上下文:
public class MyMonitorManager 
{
   private readonly IServiceScopeFactory _scopeFactory; 
   public class MyMonitorManager(IServiceScopeFactory scopeFactory) => _scopeFactory = scopeFactory;

    public void SomeMethod()
    {
        using (var scope = _serviceScopeFactory.CreateScope())
        {
            var ctx = scope.ServiceProvider.GetService<MyDBContext>(); 
            // use context
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 .NET Core在另一个单例服务中注入单例服务 - .NET Core inject singleton service in another singleton service .NET 核心 DI 允许将作用域服务注入本地机器上的 singleton - .NET Core DI allowing to inject scoped service into singleton on local machine 如何创建自定义类的单例并将其注入.Net core 2.0中的其他类? “没有注册“服务”类型的服务。”? - How to create a singleton of a custom class and inject it other classes in .Net core 2.0? 'No service for type 'Services' has been registered.'? 如何在自定义类构造函数中注入单例并使用它 | .NET 核心 2 - How to inject a singleton in a custom class constructor and use it | .NET Core 2 通过注解注册 .NET Core singleton 服务 - Register .NET Core singleton service via annotation 如何将范围服务注入DbContext? 网络核心 - How to inject a scoped service into DbContext? Net Core .NET 将瞬态注入 singleton - .NET Inject transient into singleton 从.net Core 2.1中的单例服务注入范围服务 - Injecting scoped service from singleton service in .net core 2.1 托管服务和Singleton服务之间的.NET核心差异 - .NET Core Difference between Hosted Service and Singleton Service .NET Core 2剃刀页面的Singleton Service属性未更新 - Singleton Service properties not updated .net core 2 razor pages
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM