繁体   English   中英

EF Core:通过将注入的 DbContext object 作为参数传递来创建 object

[英]EF Core: Create an object by passing an injected DbContext object as parameter

我已经创建了一个.Net Core MVC 项目并了解依赖注入如何为我们的 MVC controller 工作,如下所示,但就像我想为我自己的 ZA2F2ED4F8EBC2CBB4C21A29DC40AB61D 调用相同的参数来创建 object 一样。

public class ShiftsController : BaseController
{
  ShardingDbContext _dbContext;

   public ShiftsController(ShardingDbContext ShardingDbContext) : base(ShardingDbContext)
  {
   _dbContext = ShardingDbContext;
    ViewBag.Menu = BuildMenu();
  }

我已将 DbContext 注入到我的 Startup.cs 文件中,如下所示,

 //Entity Framework Core
 services.AddDbContext<ShardingDbContext>(options => options.UseSqlServer(ConnectionString), 
 ServiceLifetime.Transient);

ShiftsController 是一个 C#-MVC controller,当我运行我的应用程序和 go 到我的应用程序中的 Shift 页面时,DbContext 运行良好,但是当我尝试下面给出的代码时,它不起作用并给出错误。 所以我不知道如何在使用“new”关键字创建 object 时传递注册类的 object。

public class JobScheduler
{
  ShardingDbContext _dbContext;


  public JobScheduler(ShardingDbContext ShardingDbContext)
  {
      _dbContext = ShardingDbContext;

  }...

这是我自己的 class 并尝试为 class JobScheduler 创建一个 object,如下所示。

  JobScheduler  jobs = new JobScheduler();

所以现在我不知道如何将 EF 核心的 DbContext 的 object 传递给构造函数 JobScheduler,DI 适用于 controller 但不适用于普通的 ZA2F2ED4F8EBC2CBB1C21A29DC40。 任何人都可以帮助解决这个问题,我也急切地等待理解这个逻辑吗?

你是对的:你的 DI 工作正常,但你的ShardingDbContext没有传递到你的JobScheduler因为你没有使用 DI 来实例化JobScheduler 每当您使用new的关键字显式创建 object 实例时,您都没有使用 DI。

你有两个选择:

  1. 无论你在哪里调用new JobScheduler()让 DI 通过构造函数为你注入一个ShardingDbContext并将其传递给 JobScheduler 就像这样new JobScheduler(shardingDbContext)
  2. JobScheduler也注册到依赖注入中,让 DI 构建整个链,这样您就不需要调用new JobScheduler()而是在需要的地方直接注入JobScheduler

编辑

正如这里所要求的,是使用短期数据库上下文的定时作业的示例:

public class TimedBackgroundService : IHostedService, IDisposable
{
    private readonly Timer timer;
    private readonly IServiceProvider serviceProvider;

    public TimedBackgroundService(IServiceProvider serviceProvider)
    {
        timer = new Timer(async state => await ExecuteAsync());
        this.serviceProvider = serviceProvider;
    }

    public Task StartAsync(CancellationToken stoppingToken)
    {
        timer.Change(0, TimeSpan.FromMinutes(30));

        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken stoppingToken)
    {
        timer.Change(Timeout.Infinite, 0);

        return Task.CompletedTask;
    }

    public void Dispose() => timer.Dispose();

    private async Task ExecuteAsync()
    {
        try
        {
            using var scope = serviceProvider.CreateScope();
            var job = scope.ServiceProvider.GetRequiredService<MyJob>();

            await job.Execute();
        }
        catch (Exception exception)
        {
            // log error here
            return;
        }
    }
}

MyJob class 看起来像这样:

public class MyJob
{
    private readonly ShardingDbContext dbContext;

    public MyJob(ShardingDbContext dbContext)
    {
        this.dbContext = dbContext;
    }

    public Task Execute()
    {
        // Your logic goes here
    }      
}

然后你像这样在启动中注册你的类:

services
    .AddHostedService<TimedBackgroundService>()
    .AddScoped<MyJob>();

现在你有一个工作每 30 分钟运行一次,并且使用一个短暂的数据库上下文。

像这样注册您的 JobScheduler:

services.AddSingleton<JobScheduler>();

然后像这样使用你的 dbContext:

public class JobScheduler
{
   private readonly IServiceProvider provider;

   public JobScheduler(IServiceProvider provider)
   {
       

   }...


   public (or private etc) DoYourJob()
   {
        using (var scope = provider.CreateScope()) 
        {
            var dbContext = scope.GetService<ShardingDbContext>();
            //use it here
        }
   }

在 Startup.cs class 的 ConfigureServices 方法的末尾,我没有更改 JobScheduler 类中的任何内容,并从服务提供商传递 DbContext object,如下所示,感谢所有试图帮助解决这个问题的人。

 public void ConfigureServices(IServiceCollection services)
 { 
   ...
   ...

   JobScheduler job = new 
   JobScheduler(services.BuildServiceProvider().CreateScope().ServiceProvider
   .GetService<ShardingDbContext>());
   
   job.Start();
  }

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM