【问题标题】:How to read appsettings.json in context in another project? Asp.Net Core如何在另一个项目的上下文中读取 appsettings.json? ASP.NET 核心
【发布时间】:2018-05-27 18:47:36
【问题描述】:

我需要在两个地方使用相同的ConnectionString。在我的 Web 项目 Insig.Api 中,其中包含来自 appsettings.jsonConnectionString 和另一个项目类库 Insing.Infrastructure 我的数据库上下文在哪里。

Insig.Api - Startup.cs

public class Startup
    {
        public IConfiguration Configuration { get; }

        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            services.AddSingleton(Configuration);
            services.AddDbContext<InsigContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
        }
    }

Insig.Infrastructure - InsigContext.cs

public class InsigContext : DbContext, IDesignTimeDbContextFactory<InsigContext>
{
    public InsigContext() { }

    public InsigContext(DbContextOptions<InsigContext> options) : base(options) { }

    public DbSet<Sample> Samples { get; set; }

    public InsigContext CreateDbContext(string[] args)
    {    
        var builder = new DbContextOptionsBuilder<InsigContext>();    

        builder.UseSqlServer("Data Source=.\\SQLEXPRESS;Initial Catalog=InsigDB;Integrated Security=True;MultipleActiveResultSets=True");
   // Here I would like to use ConnectionString instead of raw string.    

        return new InsigContext(builder.Options);
    }
}

正如您所见,由于迁移(来自 Code First 方法),上下文中也需要 ConnectionString


编辑 - 下面的代码不起作用。当我尝试Add-Migration Init 时,我收到一个错误:Value cannot be null. Parameter name: connectionString

public class InsigContext : DbContext
    {
        private readonly string _connectionString;    

        public InsigContext(DbContextOptions<InsigContext> options, IConfiguration configuration) : base(options)
        {
            _connectionString = configuration.GetSection("ConnectionStrings:DefaultConnection").Value;
        }

        public InsigContext() { }

        public DbSet<Sample> Samples { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                optionsBuilder.UseSqlServer(_connectionString);
            }
        }
    }

【问题讨论】:

    标签: c# asp.net-core


    【解决方案1】:

    您可以将IConfiguration 注入您的InsigContext 构造函数并使用它来获取连接字符串

    private readonly string connectionString;
    public InsigContext(DbContextOptions<InsigContext> options,IConfiguration configuration)
                                                                              : base(options)
    { 
       this.connectionString = configuration.GetSection("ConnectionStrings:DefaultConnection")
                                         .Value;
    }
    // you can use this.connectionString now
    

    IConfiguration 定义在 Microsoft.Extensions.Configuration 命名空间中。所以你可能想在你的类库中添加对它的引用。

    如果您想在其他方法中访问 IConfiguration 对象,请创建一个局部变量并在您的构造函数中设置它

    private readonly IConfiguration configuration;
    public InsigContext(IConfiguration configuration)
    {
        this.configuration = configuration;
    }
    
    public void CreateDbContext(string[] args)
    {
       // you can use this.configuration here as needed or get conn string
    }
    

    不需要多个构造函数。在注入所需依赖项的位置保留一个构造函数。

    【讨论】:

    • 您可以在该方法中使用this.connectionString
    • 我有同样的想法,但检查方法CreateDbContext 实际上使用这个构造函数来创建新对象。那我应该通过什么?
    • 不确定您为什么要手动创建对象/您正在尝试做什么。但是您始终可以在 IConfiguration 类型的类中创建一个私有变量,并在您的 CreateDbContext 中使用它
    • 请检查我的编辑。我不确定我做错了什么。
    • 好吧,没关系。还是不行。 IConfiguration 的注入可能在它是不同的项目时不起作用。
    【解决方案2】:

    我决定提供更多信息for my comment

    和作者一样,我在将连接字符串从 API 项目传递到数据项目时遇到了同样的问题。我决定使用连接字符串指定全局设置并将它们链接到两个项目。我一步一步走了through this article。结果我设法在两个地方使用了连接字符串。

    【讨论】:

      【解决方案3】:

      您应该使用依赖注入在您的其他项目中注入 IConfiguration 接口。像这样:

      private readonly IConfiguration _config;
      
      public InsigContext(IConfiguration config) {
          _config = config;
      }
      

      然后你可以使用_config.GetConnectionString("DefaultConnection");方法获取连接字符串。

      【讨论】:

      • 如果我理解正确,作者需要在数据层项目中提供连接字符串,以防他绕过 ASP.Net Core 项目直接在数据层项目中操作迁移和更新数据库。例如,当开发人员在 PowerShell 中编写命令 dotnet ef database infodotnet ef dbcontext info 时,就会发生这种情况。 So DI doesn't work in this way.
      猜你喜欢
      • 1970-01-01
      • 2018-11-21
      • 1970-01-01
      • 1970-01-01
      • 2019-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-05
      相关资源
      最近更新 更多