从控制台运行dotnet核心应用程序时无法解决依赖关系

时间:2017-06-12 19:00:11

标签: c# postgresql angular .net-core

我正在编写一个客户端 - 服务器应用程序,使用Dotnet Core web-api作为后端,Angular2作为前端。持久层使用EntityFramework Core来访问postgre数据库。为了尝试我的应用程序,我添加了一个数据库种子类来创建一些要使用的测试数据。有了这堂课,我的问题开始了。

当我从Visual Studio Code运行应用程序时,一切正常。如果我使用“dotnet run”从终端启动应用程序,我会得到以下异常:

Unhandled Exception: System.Exception: Could not resolve a service of type 'OpenGameListApp.Data.DbSeeder' for the parameter 'dbSeeder' of method 'Configure' on type 'OpenGameListApp.Startup'. ---> System.ArgumentNullException: Value cannot be null.
Parameter name: connectionString
   at Microsoft.EntityFrameworkCore.Utilities.Check.NotEmpty(String value, String parameterName)
   at Microsoft.EntityFrameworkCore.NpgsqlDbContextOptionsExtensions.UseNpgsql(DbContextOptionsBuilder optionsBuilder, String connectionString, Action`1 NpgsqlOptionsAction)
   at OpenGameListApp.Startup.<ConfigureServices>b__4_0(DbContextOptionsBuilder options) in /home/noam/projects/dotnet/OpenGameListApp/src/Startup.cs:line 43
   at Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.DbContextOptionsFactory[TContext](IServiceProvider applicationServiceProvider, Action`2 optionsAction)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass16_0.<RealizeService>b__0(ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.AspNetCore.Hosting.Internal.ConfigureBuilder.Invoke(Object instance, IApplicationBuilder builder)
   --- End of inner exception stack trace ---
   at Microsoft.AspNetCore.Hosting.Internal.ConfigureBuilder.Invoke(Object instance, IApplicationBuilder builder)
   at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app)
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
   at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
   at OpenGameListApp.Program.Main(String[] args) in /home/noam/projects/dotnet/OpenGameListApp/src/Program.cs:line 15

Startup.cs类的代码:

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services
    services.AddMvc();

    // Add entity framework
    services.AddEntityFrameworkNpgsql()
        .AddDbContext<ApplicationDbContext>(options => 
            options.UseNpgsql(Configuration["Data:DefaultConnection:ConnectionString"]));    

    // Add database seeder
    services.AddSingleton<DbSeeder>();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, DbSeeder dbSeeder)
{
    // Add logger
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    // Rewrite all routing urls including the root one to the index.html file by adding the following rules
    var rewriteOptions = new RewriteOptions().AddIISUrlRewrite(env.ContentRootFileProvider, "rewrite-rules.xml");

    // Add iis url rewrite features to kestrel            
    // Note: the app.UseRewriter method must be called before app.UseDefaultFiles and app.UseStaticFiles
    app.UseRewriter(rewriteOptions);

    // In order for your Web app to serve a default page without the user having to fully qualify the URI,
    app.UseDefaultFiles();

    // Enable service of static files in wwwroot folder
    app.UseStaticFiles(new StaticFileOptions()
    {
        OnPrepareResponse = (context) => 
        {
            // Disable caching for all static files
            context.Context.Response.Headers["Cache-Control"] = Configuration["StaticFiles:Headers:Cache-Control"];
            context.Context.Response.Headers["Pragma"] = Configuration["StaticFiles:Headers:Pragma"];
            context.Context.Response.Headers["Expires"] = Configuration["StaticFiles:Headers:Expires"];
        }
    });

    // Enable the use of asp.net mvc framework
    app.UseMvc();     

    // Initialize auto mapper
    Mapper.Initialize(cfg => cfg.CreateMap<Item, ItemViewModel>());

    // Seed database
    dbSeeder.SeedIt();               
}

如果从Startup类中删除dbSeeder,则异常消失。如果有人能够向我指出这里发生了什么,我真的很感激。

1 个答案:

答案 0 :(得分:2)

Martin Ullrich的评论指出了我正确的方向:

  

看起来无法从配置中读取连接字符串,因为调用UseNpgsql()会抛出

确实无法从配置中读取连接字符串。在我的项目中,我有两个不同的appsettings文件:appsettings.development.jsonappsettings.json。只有前者包含连接字符串。当我在Visual Studio Code中运行应用程序时,它在调试环境中启动,因此能够读取连接字符串。

但是,使用dotnet run从终端运行应用程序似乎在生产环境中运行应用程序。将终端中使用的环境更改为开发(export ASPNETCORE_ENVIRONMENT=Development)后,一切正常。