问题描述
到目前为止,我使用 EFCore (3.1) 开发了多个 ASP.NET Core Web 应用程序,其中我在同一个项目中拥有所有层(模型、数据访问、业务逻辑...)。为了向 DbContext 提供数据库连接字符串,我使用了 DependencyInjection 并在 AddDbContext
方法中调用了 ConfigureServices
,如下所示:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DbContextName>(options => options.UsesqlServer(Configuration.GetConnectionString("DefaultConnection")));
// ...
}
然后我通过每个控制器类中的构造函数获得了上下文的一个实例,并用它与数据库进行交互。连接字符串始终存储在 Web 应用程序的 appsettings.json 文件中。
现在我正在开发一个基于 EF 5 的更复杂的应用程序,它包含每个层的单独项目,包括一个用于数据访问层的项目。为了避免解决方案中的每个项目都有无数个单独的配置文件,我仍然希望将数据库连接字符串存储在 appsettings.json 文件中。
如何将 appsettings.json 文件中的连接字符串提供给 DataAccess 项目中的 DbContext?由于我无法访问 DataAccess 项目内 OnConfiguring
方法中的配置,因此我无法以这种方式提供它。是否仍然可以像以前一样通过 AddDbContext
执行此操作,或者通常如何执行此操作?到目前为止,我能找到的所有示例都只适用于硬编码的连接字符串,因此在任何示例中都没有对此进行解释。
解决方法
1.您可以通过创建单例服务来提供连接字符串来解决:
在共享项目中定义 IConnectionStringProvider
接口。
public interface IConnectionStringProvider
{
public string DefaultConnectionString {get;}
}
在您的 Web 项目中,您将实现服务以提供连接字符串。
public sealed class ConnectionStringProvider : IConnectionStringProvider
{
private readonly IConfiguration _configuration;
public ConnectionStringProvider(IConfiguration configuration)
{
_configuration = configuration;
}
public string DefaultConnectionString => _configuration.GetConnectionString("DefaultConnection");
}
服务注册:
public class Startup
{
// ...
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IConnectionStringProvider,ConnectionStringProvider>();
// ...
}
// ...
}
最后你可以在你的 DAL 项目中注入 IConnectionStringProvider
,检查下面的例子(假设你的类名是 DAL
)。
public class DAL
{
// ...
private readonly IConnectionStringProvider _connectionStringProvider;
public DAL(IConnectionStringProvider connectionStringProvider)
{
_connectionStringProvider = connectionStringProvider;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DbContextName>(options => options.UseSqlServer(_connectionStringProvider.DefaultConnectionString));
// ...
}
// ...
}
重要说明:DAL
类应注册为服务。
2. 另一种方法是创建一个扩展方法来注册您的 DAL 服务并将 IConfiguration
接口作为参数传递。类似的东西:
public static class DALServices
{
public static IServiceCollection AddDALServices(this IServiceCollection services,IConfiguration configuration)
{
services.AddDbContext<DbContextName>(options => options.UseSqlServer(configuration.GetConnectionString("DefaultConnection")));
// ...
return services;
}
}
PS:您需要在 DAL 项目中安装 Nuget 包:Microsoft.Extensions.Configuration
从 Starup
类调用扩展方法:
public class Startup
{
// ...
public void ConfigureServices(IServiceCollection services)
{
services.AddDALServices(IConfiguration);
// ...
}
// ...
}