.NET Framework迁移至.NET Core:DbConnectionFactory适配问题
我刚好之前处理过类似的迁移场景,咱们一步步来解决你的两个核心问题,再聊聊松耦合的实现思路:
问题1:获取连接字符串和提供程序名称(替代ConfigurationManager.ConnectionStrings)
.NET Core 2.0已经弃用了System.Configuration.ConfigurationManager,转而使用Microsoft.Extensions.Configuration体系来读取配置。你需要做这些步骤:
首先安装必要的NuGet包:
Install-Package Microsoft.Extensions.Configuration.Json Install-Package Microsoft.Extensions.Configuration.Binder(如果用其他配置源比如环境变量、XML,安装对应的包即可)
在
appsettings.json里配置连接字符串(支持包含ProviderName):{ "ConnectionStrings": { "YourDbName": { "ConnectionString": "Server=.;Database=YourDb;Trusted_Connection=True;", "ProviderName": "Microsoft.Data.SqlClient" // 替换为对应数据库的提供程序名称 } } }在代码中读取配置:
你可以通过依赖注入获取IConfiguration(ASP.NET Core项目推荐),或者手动构建配置对象(比如控制台项目)。重构后的构造函数示例如下:using Microsoft.Extensions.Configuration; using System.Data.Common; public class ConnectionFactory { protected readonly DbProviderFactory Factory; protected readonly string ConnectionString; // 构造函数注入IConfiguration(ASP.NET Core项目首选) public ConnectionFactory(IConfiguration configuration, string connectionStringName) { // 读取连接字符串配置节点 var connectionConfig = configuration.GetSection($"ConnectionStrings:{connectionStringName}"); var providerName = connectionConfig["ProviderName"]; this.ConnectionString = connectionConfig["ConnectionString"]; // 后续获取工厂的逻辑看问题2 this.Factory = DbProviderFactories.GetFactory(providerName); } // 手动构建配置的方式(适合控制台等非Web项目) // public ConnectionFactory(string connectionStringName) // { // var config = new ConfigurationBuilder() // .AddJsonFile("appsettings.json") // .Build(); // var connectionConfig = config.GetSection($"ConnectionStrings:{connectionStringName}"); // // ... 后续逻辑同上 // } public DbConnection Connection { get { var con = Factory.CreateConnection(); con.ConnectionString = this.ConnectionString; return con; } } }这里的
connectionConfig就是.NET Core里替代ConnectionStringSettings的实现,你可以直接从配置节点读取ProviderName和ConnectionString。
问题2:通过提供程序名称获取DbProviderFactory
.NET Core 2.0中DbProviderFactories.GetFactory方法依然可用,但有个关键前提:必须先引入对应数据库的NuGet包,因为这些包会自动把提供程序注册到工厂中。
举几个常见数据库的依赖包示例:
- SQL Server:安装
Microsoft.Data.SqlClient(.NET Core推荐)或System.Data.SqlClient - MySQL:安装
MySqlConnector - PostgreSQL:安装
Npgsql
安装对应包后,你就可以直接调用DbProviderFactories.GetFactory(providerName)获取工厂,用法和.NET Framework中一致。如果遇到找不到提供程序的情况,可以手动注册(大部分场景下包会自动处理):
DbProviderFactories.RegisterFactory("Microsoft.Data.SqlClient", Microsoft.Data.SqlClient.SqlClientFactory.Instance);
松耦合数据库连接工厂的其他思路
如果想进一步降低耦合度,脱离基于字符串的提供程序名称,可以试试这些方案:
1. 依赖注入直接注入DbConnection
在ASP.NET Core的Startup.cs中直接注册具体的DbConnection:
services.AddScoped<DbConnection>(sp => { var config = sp.GetRequiredService<IConfiguration>(); var connString = config.GetSection("ConnectionStrings:YourDbName")["ConnectionString"]; return new Microsoft.Data.SqlClient.SqlConnection(connString); });
业务代码直接注入DbConnection即可,完全不需要工厂类,耦合度最低。
2. 抽象工厂模式+依赖注入
先定义一个抽象工厂接口:
public interface IDbConnectionFactory { DbConnection CreateConnection(); }
然后为每个数据库实现具体的工厂:
public class SqlServerConnectionFactory : IDbConnectionFactory { private readonly string _connectionString; public SqlServerConnectionFactory(IConfiguration configuration) { _connectionString = configuration.GetSection("ConnectionStrings:YourDbName")["ConnectionString"]; } public DbConnection CreateConnection() { return new Microsoft.Data.SqlClient.SqlConnection(_connectionString); } }
最后在Startup.cs中注册:
services.AddScoped<IDbConnectionFactory, SqlServerConnectionFactory>();
这种方式完全类型安全,避免了字符串硬编码,切换数据库实现只需要替换注册的具体工厂类即可。
3. 使用EF Core管理连接
如果项目已经引入EF Core,可以直接通过DbContext获取连接,EF Core会自动处理连接的创建和管理,进一步简化代码:
public class YourDbContext : DbContext { public YourDbContext(DbContextOptions<YourDbContext> options) : base(options) { } // 业务代码中直接调用 Database.GetDbConnection() 获取连接 }
内容的提问来源于stack exchange,提问作者managerger

