Hen*_*sas 6 c# structuremap dependency-injection dapper
我试图了解如何使用Dapper(IDbConnection)依赖注入,并仍然能够使用内置的dispose.
我在网上发现了一些文章,但我觉得很容易理解.
我想弄清楚的是如何使这个简单的类可测试:
public class UserProfileRepository : IUserProfileRepository
{
private readonly IConfigRepository _configRepository;
public UserProfileRepository(IConfigRepository configRepository)
{
_configRepository = configRepository;
}
public UserProfile GetUserProfile(string userId)
{
const string query = @"Select UserId, UserName
From Users
Where UserId = @UserId";
using (var conn = new SqlConnection(_configRepository.GetConnectionString("MyConnectionString")))
{
conn.Open();
return conn.Query<UserProfile>(query, new { UserId = userId }).SingleOrDefault();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个看起来像这样的配置库,所以我可以模拟对web.config的请求:
public class ConfigRepository : IConfigRepository
{
public string GetConnectionString(string key)
{
var conString = ConfigurationManager.ConnectionStrings[key];
if (conString != null)
{
return conString.ConnectionString;
}
return string.Empty;
}
}
Run Code Online (Sandbox Code Playgroud)
我已经读过你可以使用ConnectionFactory但是没有弄清楚如何实现它,但仍然知道我正在处理它.
谁能指出我正确的方向?
最佳连接创建机制,按照我的经验是组合DependencyInjection和ConnectionFactory。我正在摆脱IConfigRepository,因为这里所有的工作都是使用工厂完成的
优点是多方面的:
你应该做什么(在代码中):
IDBConnection在数据访问层声明对象:
[Inject] // Property Injection
public IDBConnection Connection {get; set;}
Run Code Online (Sandbox Code Playgroud)
使用像 Ninject 这样的 DI 框架声明绑定:
Bind<IDBConnection>().ToMethod(ctx =>
ConnectionFactory.CreateDbConnection("DefaultConnection"));
Run Code Online (Sandbox Code Playgroud)
如下创建 DBConnection 工厂:
连接工厂从配置文件中获取连接提供程序和连接字符串,如下所示:
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=<Value>;Initial Catalog=<Value>;User Id=<Value>;Password=<Value>" providerName="System.Data.SqlClient" />
</connectionStrings>
Run Code Online (Sandbox Code Playgroud)
标识符 is DefaultConnection,它使用 SqlClient 提供程序,但在运行时可以更改为不同的客户端,如Oracle, MySql
using System;
using System.Data.Common;
public static class ConnectionFactory
{
/// <summary>
/// Create DBConnection type based on provider name and connection string
/// </summary>
/// <param name="connectionIdentifier"></param>
/// <returns></returns>
public static DbConnection CreateDbConnection(string connectionIdentifier)
{
// Provider name setting
var providerNameValue = ConfigurationManager.ConnectionStrings[connectionIdentifier].ProviderName;
// Connection string setting
var connectionStringValue = ConfigurationManager.ConnectionStrings[connectionIdentifier].ConnectionString;
// Assume failure.
DbConnection connection;
// Null connection string cannot be accepted
if (connectionStringValue == null) return null;
// Create the DbProviderFactory and DbConnection.
try
{
// Fetch provider factory
var factory = DbProviderFactories.GetFactory(providerNameValue);
// Create Connection
connection = factory.CreateConnection();
// Assign connection string
if (connection != null)
connection.ConnectionString = connectionStringValue;
}
catch (Exception ex)
{
connection = null;
}
// Return the connection.
return connection;
}
}
Run Code Online (Sandbox Code Playgroud)
如何使用它:
对于单个调用和处理
using(Connection)
{
...
}
Run Code Online (Sandbox Code Playgroud)
对于事务上下文,按原样使用,using不需要
关于嘲讽:
您使用哪种 Mock 框架进行单元测试,您必须模拟 的结果UserProfileRepository :: GetUserProfile(string userId),这会更容易,而不是填充MockConnection使用依赖注入,这会使其变得复杂。DI 适用于实际用例,用于在运行时填充连接对象
| 归档时间: |
|
| 查看次数: |
4016 次 |
| 最近记录: |