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

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

IConfigurationRoot Configuration 

正被设置为builder.Build();

在整个MVC Web应用程序中,我可以做到

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

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

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

更新:
这是所有其他存储库inheritance的基本存储库(正如您所看到的,我现在在这里有一个硬编码连接字符串):

 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 webapp中的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应用程序中,如果我想访问任何appsettings,我可以简单地执行以下操作: Startup.Configuration["Data:DefaultConnection:ConnectionString"]

但不幸的是,我不能从我的class级图书馆做到这一点..

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

  1. 创建一个新的ASP.NET 5 MVC Web App。
  2. 将类库(包)类型的另一个项目添加到项目中。
  3. 找出将appsettings从ASP.NET 5 MVC App传递到类库的方法

更新后我仍然无法得到它。 这是我的代码:

 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()) { ... } } } 

在您的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(Configuration.GetSection("Config")); 

ConfigureServices

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

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

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

我的存储库类中有一个构造函数,它接受db连接字符串作为参数。 当我添加我的注册存储库时,这对我有用。 在startup.cs文件的ConfigureServies()中添加:

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

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

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

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

并且您的存储库cs文件正在进行构造函数注入,如下所示

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

YourDbContext将自动解析。

已经有一种扩展方法可以用来从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.cspublic void ConfigureServices(IServiceCollection services)方法中,您可以获得如下连接字符串:

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

UPDATE

我一开始不想详细说明,因为这里的问题已被标记为已回答。 但我想我可以在这里展示我的2美分。

如果确实需要将整个IConfigurationRoot对象注入到控制器中,@ Chrono会以正确的方式显示。

如果您不需要整个对象,您应该只获取连接字符串,将其传递到ConfigureServices()调用内的DbContext,并将DbContext注入到控制器中。 @Prashant Lakhlani正确地展示了它。

我只是说,在@Prashant Lakhlanipost中,您可以使用GetConnectionString扩展来代替清理代码。

您需要的是在类库项目中创建一个类来访问网站项目中的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("Data:MyDb:ConnectionString"); } return _connectionString; } public static IConfigurationRoot Configuration { get; set; } } 

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

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

在这种情况下,我在ConfigureServices中添加了Configuration作为Singleton:

 services.AddSingleton(_ => Configuration); 

我的ConnectionManager看起来像这样:

 public class ConnectionManager { private static IConfiguration currentConfig; public static void SetConfig(IConfiguration configuration) { currentConfig = configuration; } ///  /// Get a connection to the database. ///  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