使用 IConfigurationRoot 将应用程序的连接字符串向下传递到 ASP.NET 5 中的存储库类库

本文关键字:NET ASP 存储 类库 应用程序 IConfigurationRoot 连接 字符串 使用 | 更新日期: 2023-09-27 18:31:52

我有一个 ASP.NET 5 MVC Web 应用程序,并且在启动中.cs我看到公共属性

IConfigurationRoot Configuration 

正在设置为 builder.Build();

在整个MVC Web应用程序中,我可以简单地做

Startup.Configuration["Data:DefaultConnection:ConnectionString"]

appsettings.json文件中获取 conn 字符串。

如何使用构造函数注入将 ASP.NET 5 MVC 中指定的连接字符串appsettings.json传递到我的存储库类库?

更新:
以下是所有其他存储库继承的基本存储库(如您所见,我现在在这里有一个硬编码的连接字符串):

public class BaseRepo
{
    public static string ConnectionString = "Server=MYSERVER;Database=MYDATABASE;Trusted_Connection=True;";
    public static SqlConnection GetOpenConnection()
    {
        var cs = ConnectionString;
        var connection = new SqlConnection(cs);
        connection.Open();
        return connection;
    }
}

在我的appsettings.json文件中的 asp.net 5 Web应用程序中,我有以下内容,相当于在.net 4.5 web应用程序中向web.config添加连接字符串:

  "Data": {
    "DefaultConnection": {
      "ConnectionString": "Server=MYSERVER;Database=MYDATABASE;Trusted_Connection=True;"
    }
  }

此外,在我的 asp.net 5 Web 应用程序中,我的 Startup 中有以下默认代码.cs它将站点配置加载到 IConfigurationRoot 类型的公共属性中:

 public IConfigurationRoot Configuration { get; set; }
// Class Constructor
        public Startup(IHostingEnvironment env)
        {
            // Set up configuration sources.
            var builder = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
            if (env.IsDevelopment())
            {
                // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
                builder.AddUserSecrets();
            }
            builder.AddEnvironmentVariables();
            Configuration = builder.Build();
        }

现在在我的 asp.net Web 应用程序中,如果我想访问任何应用程序设置,我可以简单地执行以下操作:Startup.Configuration["Data:DefaultConnection:ConnectionString"]

但不幸的是,我无法从我的类库中执行此操作。

如果有人想尝试解决这个问题,以下是重现的步骤:

  1. 创建新的 ASP.NET MVC Web 应用。
  2. 将另一个类型为"类库(包)"的项目添加到该项目。
  3. 找出将应用设置从 ASP.NET 5 MVC 应用传递到类库的方法

更新后,我仍然无法完全理解它。这是我的代码:

public class BaseRepo
{
    private readonly IConfigurationRoot config;
    public BaseRepo(IConfigurationRoot config)
    {
        this.config = config;
    }
}

此类声明不起作用,因为 BaseRepo 现在需要一个构造函数参数。

public class CustomerRepo : BaseRepository, ICustomerRepo
{
    public Customer Find(int id)
    {
        using (var connection = GetOpenConnection())
        {
            ...
        }
    }
}

使用 IConfigurationRoot 将应用程序的连接字符串向下传递到 ASP.NET 5 中的存储库类库

在您的 Startup.cs 文件上添加以下方法

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

然后像这样更新您的 BaseRepo 类

public class BaseRepo {
    private readonly IConfiguration config;
    public BaseRepo(IConfiguration config) {
        this.config = config;
    }
    public SqlConnection GetOpenConnection() {
        string cs = config["Data:DefaultConnection:ConnectionString"];
        SqlConnection connection = new SqlConnection(cs);
        connection.Open();
        return connection;
    }
}

ASP.NET 提供了自己的传递配置设置的方式。

假设你的appSettings.json中有这个:

{
  "Config": {
    "Setting1": 1,
    "Setting2": "SO"
  }
}

然后你需要一个这样的类:

public class MyConfiguration
{
    public int Setting1 { get; set; }
    public string Setting2 { get; set; }
}

这允许您通过添加以下行来使用此配置配置服务

services.Configure<MyConfigurationDto>(Configuration.GetSection("Config"));

ConfigureServices.

然后,可以通过执行以下操作在构造函数中注入配置:

public class SomeController : Controller
{
    private readonly IOptions<MyConfiguration> config;
    public ServiceLocatorController(IOptions<MyConfiguration> config)
    {
        this.config = config;
    }
    [HttpGet]
    public IActionResult Get()
    {
        return new HttpOkObjectResult(config.Value);
    }
}

此示例适用于控制器。但是,您可以对应用程序的其他层执行相同的操作。

我的存储库类中有一个构造函数,它接受数据库连接字符串作为参数。 当我添加要注入的存储库时,这对我有用。 在启动的 ConfigureServies() 中.cs文件添加以下内容:

services.AddScoped<IRepos>(c => new Repos(Configuration["DbConnections:ConnStr1"]));

IRepos.cs是接口,Repos.cs是实现它的类。 当然,配置只是对构建IConfigurationRoot对象的引用。

一种稍微不同的方法是在类库中创建一个静态类,您可以在该类库上从Startup.cs中的Configure(..)-方法调用方法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ...
    ConnectionManager.SetConfig(Configuration);
}

在这种情况下,我在ConfigureServices中添加了配置作为单例:

services.AddSingleton(_ => Configuration);

我的ConnectionManager如下所示:

public class ConnectionManager
{
    private static IConfiguration currentConfig;
    public static void SetConfig(IConfiguration configuration)
    {
        currentConfig = configuration;
    }
    /// <summary>
    /// Get a connection to the database.
    /// </summary>
    public static SqlConnection GetConnection
    {
        get
        {
            string connectionString = currentConfig.GetConnectionString("MyConnection");
            // Create a new connection for each query.
            SqlConnection connection = new SqlConnection(connectionString);
            return connection;
        }
    }
}

这可能会也可能不会在对象生存期等方面存在一些问题,我当然不喜欢static类,但据我所知,这是一种可行的方法。您甚至可以从配置文件中提取ConnectionString并仅发送该Configuration,而不是传递。

已经有一个扩展方法可用于专门从 aspsettings.json 获取连接字符串。

  1. 在 appsettings.json 中定义连接字符串,如下所示:

     {
         "ConnectionStrings": {
             "Local": "Data source=.''SQLExpress;Initial Catalog=.......",
             "Test:": "Data source=your-server;......"
         },
         "Logging": {
             "IncludeScopes": false,
             "LogLevel": {
                 "Default": "Debug",
                 "System": "Information",
                 "Microsoft": "Information"
             }
         }
    }
    
  2. Startup.cs 内的 public void ConfigureServices(IServiceCollection services) 方法中,可以像这样获取连接字符串:

    var connectionString = this.Configuration.GetConnectionString("Local");
    
  3. GetConnectionString扩展名来自 Microsoft.Extensions.Configuration
  4. 享受:)

更新

起初我不想详细介绍,因为这里的问题已经被标记为已回答。但我想我可以在这里展示我的 2 美分。

如果您确实需要将整个IConfigurationRoot对象注入控制器,@Chrono展示了正确的方法。

如果不需要整个对象,则只需获取连接字符串,将其传递到ConfigureServices()调用中的 DbContext,然后将DbContext注入控制器。 @Prashant拉赫拉尼正确地展示了它。

我只是说,在 Lakhlani 帖子@Prashant,您可以使用GetConnectionString扩展来清理代码。

如果项目startUp.cs中的ConfigureServices包含

services.AddEntityFramework()
             .AddSqlServer()
             .AddDbContext<YourDbContext>(options =>
                 options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

并且您的存储库 CS 文件具有构造函数注入,如下所示

public class MyRepo : IRepo
{
    private readonly YourDbContext dbContext;
    public MyRepo(YourDbContext ctx)
    {
        dbContext = ctx;
    }
}

YourDbContext将自动解决。

您需要

在类库项目中创建一个类,以访问网站项目中的appsettings.json并返回连接字符串。

{
    private static string _connectionString;
    public static string GetConnectionString()
    {
        if (string.IsNullOrEmpty(_connectionString))
        {
            var builder = new ConfigurationBuilder()
           .AddJsonFile("appsettings.json");
            Configuration = builder.Build();
            _connectionString = Configuration.Get<string>("Data:MyDb:ConnectionString");
        }
        return _connectionString;
    }
    public static IConfigurationRoot Configuration { get; set; }
}