使用 DI 访问 Startup.cs 中的 NPGSQL
Accessing NPGSQL in Startup.cs using DI
使用 .NET Core 2.1、NPGSQL、Entity Framework 和 Linux。
从 Startups.cs' 配置函数,我在注入的依赖项 class 中调用一个函数,该函数又调用另一个注入的依赖项 class ,它使用 [=52= 访问数据库] + NPGSQL.
配置服务:
public void ConfigureServices(IServiceCollection services)
{
services.AddEntityFrameworkNpgsql()
.AddDbContext<MMContext>(options => options.UseNpgsql($"Host='localhost'; Port=1234;Database='mydb';Username='test';Password='test'"))
.BuildServiceProvider();
services.AddTransient<IMusicManager, MusicManager>();
services.AddTransient<IMusicRepo, MusicRepo>();
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
配置函数:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMvc();
using (var scope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
{
var mm = scope.ServiceProvider.GetRequiredService<IMusicManager>();
mm.DoSomeDBStartupStuff();
}
}
IMusicManager
实现如下所示:
private readonly IMusicRepo _musicStoreRepo;
public MusicManager(IMusicRepo musicStoreRep)
{
_musicStoreRepo = musicStoreRepo;
}
public void DoSomeDBStartupStuff()
{
_musicStoreRepo.InsertSampleStuff();
_musicStoreRepo.CheckThisAndCheckThat();
}
IMusicRepo
实现如下所示:
private readonly MMContext _context;
public MusicRepo(MMContext context)
{
_context = context;
}
public void InsertSampleStuff()
{
_context.Music.AddAsync(new music("abc"));
_context.Music.AddAsync(new music("123"));
_context.SaveChangesAsync();
}
MMContext
这是这样实现的:
public class MMContext : DbContext
{
public MMContext(DbContextOptions<MMContext> options) : base(options) {}
... OnModelCreating etc...
}
启动时出现异常:
Application startup exception: System.InvalidOperationException:
Reset() called on connector with state Executing at
Npgsql.NpgsqlConnector.Reset() at
Npgsql.ConnectorPool.Release(NpgsqlConnector connector) at
Npgsql.NpgsqlConnection.Close(Boolean wasBroken) at
Npgsql.NpgsqlConnection.Dispose(Boolean disposing) at
System.ComponentModel.Component.Dispose() at
Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Dispose()
at
Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.Dispose()
at Microsoft.EntityFrameworkCore.DbContext.Dispose() at
Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.Dispose()
at MM.Startup.Configure(IApplicationBuilder app, IHostingEnvironment
env) in \Startup.cs:line 122
--- End of stack trace from previous location where exception was thrown --- at
Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder
app) at
Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.b__0(IApplicationBuilder
app) at
Microsoft.AspNetCore.Hosting.Internal.AutoRequestServicesStartupFilter.<>c__DisplayClass0_0.b__0(IApplicationBuilder
builder) at
Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
我不确定是什么导致了这个问题。可能是我使用依赖注入的方式以及我使用范围的方式?帮助表示赞赏。
注意到 void
函数中没有等待异步调用。
public void InsertSampleStuff()
{
_context.Music.AddAsync(new music("abc"));
_context.Music.AddAsync(new music("123"));
_context.SaveChangesAsync();
}
当您尝试保存这些更改时,这可能会导致 DbContext
出现线程问题。
要么使函数异步并正确等待这些调用,要么使用同步函数 API
public void InsertSampleStuff() {
_context.Music.Add(new music("abc"));
_context.Music.Add(new music("123"));
_context.SaveChanges();
}
如果走异步路线,则考虑将该设置代码移到托管服务中并在那里适当地等待它
使用 .NET Core 2.1、NPGSQL、Entity Framework 和 Linux。
从 Startups.cs' 配置函数,我在注入的依赖项 class 中调用一个函数,该函数又调用另一个注入的依赖项 class ,它使用 [=52= 访问数据库] + NPGSQL.
配置服务:
public void ConfigureServices(IServiceCollection services)
{
services.AddEntityFrameworkNpgsql()
.AddDbContext<MMContext>(options => options.UseNpgsql($"Host='localhost'; Port=1234;Database='mydb';Username='test';Password='test'"))
.BuildServiceProvider();
services.AddTransient<IMusicManager, MusicManager>();
services.AddTransient<IMusicRepo, MusicRepo>();
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
配置函数:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMvc();
using (var scope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
{
var mm = scope.ServiceProvider.GetRequiredService<IMusicManager>();
mm.DoSomeDBStartupStuff();
}
}
IMusicManager
实现如下所示:
private readonly IMusicRepo _musicStoreRepo;
public MusicManager(IMusicRepo musicStoreRep)
{
_musicStoreRepo = musicStoreRepo;
}
public void DoSomeDBStartupStuff()
{
_musicStoreRepo.InsertSampleStuff();
_musicStoreRepo.CheckThisAndCheckThat();
}
IMusicRepo
实现如下所示:
private readonly MMContext _context;
public MusicRepo(MMContext context)
{
_context = context;
}
public void InsertSampleStuff()
{
_context.Music.AddAsync(new music("abc"));
_context.Music.AddAsync(new music("123"));
_context.SaveChangesAsync();
}
MMContext
这是这样实现的:
public class MMContext : DbContext
{
public MMContext(DbContextOptions<MMContext> options) : base(options) {}
... OnModelCreating etc...
}
启动时出现异常:
Application startup exception: System.InvalidOperationException: Reset() called on connector with state Executing at Npgsql.NpgsqlConnector.Reset() at Npgsql.ConnectorPool.Release(NpgsqlConnector connector) at Npgsql.NpgsqlConnection.Close(Boolean wasBroken) at Npgsql.NpgsqlConnection.Dispose(Boolean disposing) at System.ComponentModel.Component.Dispose() at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Dispose() at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.Dispose() at Microsoft.EntityFrameworkCore.DbContext.Dispose() at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.Dispose() at MM.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env) in \Startup.cs:line 122 --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app) at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.b__0(IApplicationBuilder app) at Microsoft.AspNetCore.Hosting.Internal.AutoRequestServicesStartupFilter.<>c__DisplayClass0_0.b__0(IApplicationBuilder builder) at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
我不确定是什么导致了这个问题。可能是我使用依赖注入的方式以及我使用范围的方式?帮助表示赞赏。
注意到 void
函数中没有等待异步调用。
public void InsertSampleStuff()
{
_context.Music.AddAsync(new music("abc"));
_context.Music.AddAsync(new music("123"));
_context.SaveChangesAsync();
}
当您尝试保存这些更改时,这可能会导致 DbContext
出现线程问题。
要么使函数异步并正确等待这些调用,要么使用同步函数 API
public void InsertSampleStuff() {
_context.Music.Add(new music("abc"));
_context.Music.Add(new music("123"));
_context.SaveChanges();
}
如果走异步路线,则考虑将该设置代码移到托管服务中并在那里适当地等待它