简体   繁体   English

使用 DI 在 Startup.cs 中访问 NPGSQL

[英]Accessing NPGSQL in Startup.cs using DI

Using .NET Core 2.1, NPGSQL, Entity Framework and Linux.使用 .NET Core 2.1、NPGSQL、实体框架和 Linux。

From Startups.cs' Configure function, I am calling a function in a dependency injected class that in turn calls another dependency injected class which accesses the DB using Entity Framework + NPGSQL.从 Startups.cs 的 Configure 函数中,我正在调用依赖注入类中的一个函数,该类又调用另一个依赖注入类,该类使用实体框架 + NPGSQL 访问数据库。

Configure Services:配置服务:

    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);
    }

Configure function:配置功能:

    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音乐管理器

Implementation looks like this:实现看起来像这样:

    private readonly IMusicRepo _musicStoreRepo;
    public MusicManager(IMusicRepo musicStoreRep)
    {
        _musicStoreRepo = musicStoreRepo;
    }

    public void DoSomeDBStartupStuff()
    {
        _musicStoreRepo.InsertSampleStuff();
        _musicStoreRepo.CheckThisAndCheckThat();
    }

IMusicRepo音乐库

Implementation looks like this:实现看起来像这样:

    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上下文

This is implemented as so:这是这样实现的:

public class MMContext : DbContext
{
    public MMContext(DbContextOptions<MMContext> options) : base(options) {}
    ... OnModelCreating etc...
}

I get this exception on firing it up:我在启动它时遇到这个异常:

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__Displa应用程序启动异常:System.InvalidOperationException:Reset() 在连接器上调用,状态为 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( ) 在 Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.Dispose() at MM.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env) in \\Startup.cs:line 122 --- 从上一个抛出异常的位置的堆栈跟踪结束--- 在 Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder 应用程序) 在 Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__Displa yClass0_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() yClass0_0.b__0(IApplicationBuilder 应用程序) 在 Microsoft.AspNetCore.Hosting.Internal.AutoRequestServicesStartupFilter.<>c__DisplayClass0_0.b__0(IApplicationBuilder builder) 在 Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()

I am not sure what is causing the issue.我不确定是什么导致了这个问题。 Possibly the way I am using Dependency Injection and the way I am using the scope?可能是我使用依赖注入的方式以及我使用范围的方式? Help appreciated.帮助表示赞赏。

Noticing async calls not being awaited in a void function.注意到没有在void函数中等待异步调用。

public void InsertSampleStuff()
{
    _context.Music.AddAsync(new music("abc"));
    _context.Music.AddAsync(new music("123"));
    _context.SaveChangesAsync();
}

This could cause threading issues with the DbContext when you try to save those changes.当您尝试保存这些更改时,这可能会导致DbContext出现线程问题。

Either make the function async and await those calls properly or use the synchronous API要么使函数异步并正确等待这些调用,要么使用同步 API

public void InsertSampleStuff() {
    _context.Music.Add(new music("abc"));
    _context.Music.Add(new music("123"));
    _context.SaveChanges();
}

If going the asynchronous route then consider moving that setup code into a hosted service and properly awaiting it there如果走异步路线,请考虑将该设置代码移动到托管服务中并在那里正确等待

Reference Reference Background tasks with hosted services in ASP.NET Core参考 参考ASP.NET Core 中带有托管服务的后台任务

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

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