【问题标题】:Getting Connection String in ASP.Net Core MVC data layer在 ASP.Net Core MVC 数据层中获取连接字符串
【发布时间】:2020-12-03 23:32:24
【问题描述】:

我正在使用下面的代码来检索连接字符串,它工作正常。但是,配置对象必须通过层。 .Net 的早期版本允许我直接在数据层中获取连接字符串。那么我仍然可以这样做(以及我该怎么做)还是需要像现在一样通过应用程序传递配置对象?

在startup.cs中

public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services)
{
   ...
   services.AddSingleton(_ => Configuration);
   ...
}

MyController.cs

public class MyController : Controller
{
  protected readonly IConfiguration Configuration;

  public MyController(IConfiguration configuration)
  {
     Configuration = configuration;
  }

  public IActionResult ListRecords()
  {
      DatabaseContext ctx = new DatabaseContext(Configuration);
      return View();
  }
}

DatabaseContext.cs

public class DatabaseContext : DbContext
{
   private readonly IConfiguration config;
   public DatabaseContext(IConfiguration config)
   {
      this.config = config;
   }

   protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
   {
      optionsBuilder.UseSqlServer(config["ConnectionStrings:Dev"]);
   }
}

【问题讨论】:

  • 您可以在 Startup 类中执行此操作。几乎在互联网上找到的每个示例都是如此。
  • 你应该注入你的数据库上下文,而不是手动创建一个。这样都是从启动类配置的

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


【解决方案1】:

必须显式注入 IConfiguration 通常被视为代码异味并表明存在设计问题。

利用依赖注入

public class MyController : Controller {
    DatabaseContext context;

    public MyController(DatabaseContext context) {
        this.context = context;
    }

    public IActionResult ListRecords() {
        //...use context here
        return View();
    }
}

并注入数据库选项

public class DatabaseContext : DbContext {    
    public DatabaseContext(DbContextOptions<DatabaseContext> options): base(options) {
        //...
    }
}

那么只需要在启动时配置上下文就可以了

public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services) {
    // ...

    services.AddDbContext<DatabaseContext>(options => 
        options.UseSqlServer(Congiguration.GetConnectionString("Dev"));

    // ...
}

【讨论】:

  • 谢谢,现在如果我调用其他层(例如业务层)在控制器中会发生什么 - 我是传递上下文还是可以通过 DI 将其作为参数调用它们的类
  • 其实这个问题是在这里问的:stackoverflow.com/questions/40862162/…
  • 如果业务层类需要上下文,再次使用DI,通过构造函数注入的方式将上下文注入BL,将BL类注入控制器。
  • 这对将 BL 注入控制器很有意义,但是如何将上下文注入 BL?我是否使用 AddDbContext 但没有带有 DBContext 的 BL 构造函数?
  • @user3807918 我想你误解了我的意思。 Do 使用 AddDbContext 并且 do 在其构造函数中有一个带有上下文的 BL 类。当框架将 BL 类注入到控制器中时,它也会创建上下文并将其注入到 BL 类中。
【解决方案2】:

通常我用于设置 DBContext 的模式是在启动时进行配置。

所以如果这是startup.cs:

        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            var sqlConnString = Configuration.GetConnectionString(dbConnectionStringSettingsName);

            services.AddDbContext<DatabaseContext >(opt => opt.UseSqlServer(sqlConnString));

此外,如果您将上下文作为服务引用传递,则不需要为其提供 IConfiguration。

    private readonly DatabaseContext _context;       

    public MyController(DatabaseContext context)
    {
        _context = context;
    }
    public IActionResult ListRecords()
    {
      var dbresults = _context.Table.ToList();
      return View(dbresults );
    }

【讨论】:

  • 我同意,您为什么不使用 Startup 来执行此操作...
【解决方案3】:

使用金块包

Install-Package Microsoft.Extensions.Configuration.Abstractions

 Install-Package Microsoft.Extensions.Configuration

然后在 Web 应用程序中注入 IConfigurationSection

https://github.com/geeksarray/read-appsettings-json-in-net-core-class-library-using-dependency-injection

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-30
    • 1970-01-01
    • 1970-01-01
    • 2017-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-18
    相关资源
    最近更新 更多