ASP.NET vNext全局配置访问

时间:2015-08-17 06:29:32

标签: asp.net asp.net-core

在ASP.NET vNext中访问config.json文件(或存储其他配置的地方)的正确/推荐方法是什么?

Startup类中,我设置了如下配置:

public class Startup
{
    public IConfiguration Configuration { get; set; }

public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
    var configurationBuilder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
        .AddJsonFile("config.json")
        .AddEnvironmentVariables();

    Configuration = configurationBuilder.Build();
}

但是如果我需要在别处访问连接字符串,我该怎么做?例如,在EF上下文的OnConfiguring中,如何获取连接字符串:

protected override void OnConfiguring(EntityOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseSqlServer( ??? );

我读过你可以用这个:

var config = Startup.Configuration
    ?? new Configuration()
        .AddJsonFile("config.json")
        .AddEnvironmentVariables();

但是(a)启动不是静态的,(b)你肯定不希望每次需要时重建配置设置 - 这是在任何地方重复使用的代码。

我还读过您应该使用Dependency Injection,但该链接并未完全告诉您如何操作。如果我的DbContext构造函数有一个注入参数,那么如何将它注入无参数的BaseApiController?

这看起来像是一个常见/简单的要求:在Startup中配置之后,如何在其他地方访问该配置?这应该在各地的文档/示例中。

2 个答案:

答案 0 :(得分:1)

以下是我所做的工作:

启动

public class Startup
{
    public IConfiguration Configuration { get; set; }

    public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
    {
        // create & store the configuration once
        var configurationBuilder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
            .AddJsonFile("config.json")
            .AddEnvironmentVariables();

        Configuration = configurationBuilder.Build();
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<Context>(options => options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

        services.AddIdentity<User, IdentityRole>()
                .AddEntityFrameworkStores<Context>()
                .AddDefaultTokenProviders();

        services.AddMvc();

        // adding/registering the dbContext for dependency injection as a singleton
        services.AddSingleton(s => new Context(Configuration));
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseIdentity();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                  name: "default",
                  template: "{controller}/{action}/{id?}",
                  defaults: new { controller = "Home", action = "Index" });
        });
    }
}

的DbContext

public sealed class Context : IdentityDbContext<IdentityUser>
{
    private readonly IConfiguration _config;
    public DbSet<Client> Clients { get; set; }

    public Context(IConfiguration config)
    {
        // store the injected config
        _config = config;
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ForSqlServer().UseIdentity();
        base.OnModelCreating(modelBuilder);
    }

    protected override void OnConfiguring(EntityOptionsBuilder optionsBuilder)
    {
        // use the injected config
        optionsBuilder.UseSqlServer(_config.Get("Data:DefaultConnection:ConnectionString"));

        base.OnConfiguring(optionsBuilder);
    }
}

控制器

[Route("api/[controller]")]
public class TestController : BaseController
{
    private readonly Context _context;

    // have the context injected
    public TestController(Context context)
    {
        _context = context;
    }

    [HttpGet]
    public ActionResult Get()
    {
        return new ObjectResult(_context.Clients.ToList());
    }
}

答案 1 :(得分:1)

首先,您应该避免将数据库上下文注册为单例。传递原始IConfiguration界面也不是一个好习惯。

可以创建一个POCO选项类:

public class DbOptions
{
    public string ConnectionString { get; set }
}

使用config.json中的部分填充ConfigureServices方法:

services.Configure<DbOptions>(Configuration.GetConfigurationSection("Data:DefaultConnection"));

然后你可以把它注入你的DbContext(以及控制器等):

public sealed class Context : IdentityDbContext<IdentityUser>
{
    private readonly DbOptions _options;

    public DbSet<Client> Clients { get; set; }

    public Context(IOptions<DbOptions> optionsAccessor)
    {
        // store the injected options
        _options = optionsAccessor.Options;
    }

    // other code..
}