使用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级图书馆做到这一点..
如果有人想尝试解决这个问题,那么重现的步骤如下:
- 创建一个新的ASP.NET 5 MVC Web App。
- 将类库(包)类型的另一个项目添加到项目中。
- 找出将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专门获取连接字符串。
-
在appsettings.json中定义连接字符串,如下所示:
{ "ConnectionStrings": { "Local": "Data source=.\\SQLExpress;Initial Catalog=.......", "Test:": "Data source=your-server;......" }, "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Debug", "System": "Information", "Microsoft": "Information" } } }
-
在
Startup.cs
的public void ConfigureServices(IServiceCollection services)
方法中,您可以获得如下连接字符串:var connectionString = this.Configuration.GetConnectionString("Local");
-
GetConnectionString
扩展来自Microsoft.Extensions.Configuration
。 - 请享用 :)
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.cs
的Configure(..)
-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
。