![](/img/trans.png)
[英]EF Core seeding data in Sqlite and WPF with relational model - unable to create an object of type DbContext error
[英]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。
你有两个选择:
new JobScheduler()
让 DI 通过构造函数为你注入一个ShardingDbContext
并将其传递给 JobScheduler 就像这样new JobScheduler(shardingDbContext)
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.