【问题标题】:Dependency Injection with configuration in .net core在 .net 核心中配置依赖注入
【发布时间】:2019-09-13 16:47:02
【问题描述】:

我正在尝试通过在 .net 核心项目的类中获取配置来注入依赖项。我试图注入依赖项的类在另一个项目中。但不知何故,我无法从注入依赖项的配置文件中获取值。 下面是我的代码

在下面的 DBContext 中,我需要从配置中获取值,其中我使用了 DBConfiguration 类的 DI。

public class DBContext : DbContext
    {
        private readonly DBConfiguration _dBConfiguration;

        public DBContext(DBConfiguration dBConfiguration)
        {
            _dBConfiguration = dBConfiguration;
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(_dBConfiguration.ConnectionString);
            base.OnConfiguring(optionsBuilder);
        }

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

还有我在 web api 中的 StartUp.cs 文件

public void ConfigureServices(IServiceCollection services)
        {
            services.AddScoped<DBConfiguration>();

            services.AddEntityFrameworkSqlServer().AddDbContext<DBContext>();

            services.AddOptions();

            services.Configure<DBConfiguration>(Configuration.GetSection("DBConfiguration"));

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

还有我的 appsettings.json 文件

{
  "DBConfiguration": {


         "ConnectionString": "Server=myserver;Database=BaseProjectDB;Trusted_Connection=True;MultipleActiveResultSets=true",
         "ApplicationName": "WebAPI"


  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

对此的任何帮助表示赞赏!

【问题讨论】:

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


    【解决方案1】:

    当您在 DBContext 中注入 DBConfiguration 时,您似乎在 StartUp 文件中使用 DBConfigurationOptions。

    这是我目前使用我的配置的方式:

    public class Startup
    {
        private readonly IConfiguration _configuration;
    
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables();
    
            _configuration = builder.Build();
        }
    
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<DBConfigurationOptions>(_configuration.GetSection("DBConfiguration"));
        }
    }
    

    然后它被注入为:

    public class DBContext : DbContext
    {
        private readonly DBConfigurationOptions _dBConfiguration;
    
        public DBContext(IOptions<DBConfigurationOptions> dBConfiguration)
        {
            _dBConfiguration = dBConfiguration.Value;
        }
    }
    

    【讨论】:

    • 是的..这只是我试图使用它的选项...正如有人在网上建议使用数组的东西..我也已经尝试过使用 DBConfiguration ..但在那种情况下也来空
    • 我不完全确定(我已经有一段时间没有设置这样的东西了,而且我还没有永远使用实体框架),但也许你应该在你的启动中移动配置上面添加了Sql Server。另外,我将通过一个我们如何使用配置的示例来编辑我的答案,因为这可能有用。
    【解决方案2】:

    为什么不在你也有配置的地方直接配置db呢?
    在您的 DBContext 类中(顺便说一句,您可能应该为此选择一个更好的名称),您只需要公开这样的构造函数,不需要覆盖 OnConfiguring 或类似的东西。

    这个类可以在任何你想要的程序集中。

    class DBContext : DbContext
    {
        public DBContext(DbContextOptions<DBContext> options) : base(options)
        {
        }
    }
    

    对于配置,您可以只使用内置的 optionsBuilder-action(放置在 ConfigureServices 方法内):

    services.AddEntityFrameworkSqlServer()
        .AddDbContext<DBContext>(optionsBuilder =>
            optionsBuilder.UseSqlServer(
                Configuration.GetSection("DBConfiguration").Get<DBConfiguration>().ConnectionString)
        );
    

    目前您获取配置的方式肯定可以改进。例如,您可以这样做:

    var DBConfig = Configuration.GetSection("DBConfiguration").Get<DBConfiguration>();
    services.AddSingleton(DBConfig);// <- now you can inject that if you want but it's not necessary
    
    // now we don't need to get the config here
    services.AddEntityFrameworkSqlServer()
        .AddDbContext<DBContext>(optionsBuilder =>
            optionsBuilder.UseSqlServer(DBConfig.ConnectionString)
        );
    

    还有一些其他方面您可能需要改进,例如更好地命名DBContext,而不是覆盖您没有特定实现的成员(就像您对OnModelCreating 所做的那样)。

    另外,下次您应该包含不属于某种公共 API 的所有类,例如您的 DBConfiguration 类。

    【讨论】:

    • 感谢您的帮助!我这样做的原因是我试图使 DAL 具有可行的通用功能,因此我也可以在新项目中使用相同的 DAL
    【解决方案3】:

    要接收配置,您必须从DBContext 修改构造函数的签名

    public DBContext(DBConfiguration dBConfiguration)
    

    public DBContext(IOptions<DBConfiguration> dBConfiguration)
    

    正确接收选项(不要忘记添加命名空间Microsoft.Extensions.Options)。

    此外,您需要使用配置文件中的属性在某处定义DBConfiguration 类。

    【讨论】:

    • 但是如果没有 IOptions 接口我们不能使用这个?
    • 我不这么认为。如果您通过services.Configure 将选项添加到服务集合中,您将通过IOptionsinterface 接收它们。这就是它的设计方式。
    猜你喜欢
    • 2018-01-03
    • 2018-12-14
    • 1970-01-01
    • 2019-02-16
    • 2021-03-02
    • 2020-01-17
    • 2017-12-09
    • 2019-01-31
    • 2019-11-18
    相关资源
    最近更新 更多