使用DI访问Startup.cs中的NPGSQL

时间:2019-06-28 11:22:11

标签: c# asp.net-core dependency-injection entity-framework-core npgsql

使用.NET Core 2.1,NPGSQL,实体框架和Linux。

在Startups.cs的Configure函数中,我在依赖注入类中调用一个函数,该类又调用了另一个依赖注入类,该类使用Entity Framework + 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...
}

启动时会出现此异常:

  

应用程序启动异常:System.InvalidOperationException:   在状态为Executing的连接器上调用Reset()   Npgsql.NpgsqlConnector.Reset()在   Npgsql.ConnectorPool.Release(NpgsqlConnector连接器)位于   Npgsql.NpgsqlConnection.Close(Boolean wasBroken)在   Npgsql.NpgsqlConnection.Dispose(布尔处置)位于   System.ComponentModel.Component.Dispose()在   Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Dispose()   在   Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.Dispose()   在Microsoft.EntityFrameworkCore.DbContext.Dispose()在   Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.Dispose()   在MM.Startup.Configure(IApplicationBuilder应用程序,IHostingEnvironment   env)在\ Startup.cs:第122行   ---从上一个引发异常的位置开始的堆栈跟踪-   Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder   应用)   Microsoft.AspNetCore.HostFilteringStartupFilter。<> c__DisplayClass0_0.b__0(IApplicationBuilder   应用)   Microsoft.AspNetCore.Hosting.Internal.AutoRequestServicesStartupFilter。<> c__DisplayClass0_0.b__0(IApplicationBuilder   建筑商)   Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()

我不确定是什么引起了问题。可能是我使用依赖关系注入的方式以及我使用范围的方式?帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

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

如果要使用异步路由,请考虑将设置代码移入托管服务,并在那里适当等待

参考参考Background tasks with hosted services in ASP.NET Core