我正在使用asp.net core 2.0和dapper。我有一个包装IDbConnection接口的类,只暴露某些方法。这是该课程的简短版本。
public class MyConnectionString : IMyConnectionString
{
private readonly IDbConnection _connection;
public int ConnectionTimeout => _connection.ConnectionTimeout;
public string Database => _connection.Database;
public string ConnectionString { get => null; set => _connection.ConnectionString = value; }
public ConnectionState State => _connection.State;
public MyConnectionString(IOptions<ConnectionProviderOptions> connProvOpts, EncryptionHelper encHelper)
{
var con = "some logic to get the connection string.";
_connection = new SqlConnection(con);
}
public int Execute(string query, object parameters = null)
{
using (var con = _connection) { return con.Execute(query, parameters); }
}
}
我通过构造函数将此类注入到我的Repository服务中。例如,这是一个可以调用它的方法:
internal class SomeRepository
{
private readonly IMyConnectionString _connection;
public SomeRepository(IMyConnectionString connection)
{
_connection = connection;
}
public void ExecuteSomeQuery(Object params)
{
var query = "Some query...";
_connection.Execute(query, params);
}
}
现在的问题是,如果我在单个请求中调用_connection.Execute(query, params);
两次(2个不同的服务),则第二次调用ConnectionString
类中的MyConnectionString
值为空。我试过在Transient和Request范围内绑定它,看它是否会保留它,但没有运气。任何关于为什么会发生这种情况的想法或者如何保留它以便我不必在每次请求时都创建连接字符串?
答案 0 :(得分:2)
将Connection
包裹在using
内,将Connection
置于执行结束处:正如@Jasen在评论中所述。
在您的情况下,我会在构造函数中创建的Connection
上获取连接并执行:完全删除using
。
您不应创建SqlConnection
,因为您正在实现依赖注入。你应该:
IDisposable
以在收集课程时处理您的连接。SqlConnection
工厂创建SqlConnection
,从班级中分离您的创作逻辑。你的课应该像这样:
public class MyConnectionString : IMyConnectionString
{
private readonly IDbConnection _connection;
public int ConnectionTimeout => _connection.ConnectionTimeout;
public string Database => _connection.Database;
public string ConnectionString
{
get => null;
set => _connection.ConnectionString = value;
}
public ConnectionState State => _connection.State;
public MyConnectionString(IOptions<ConnectionProviderOptions> connProvOpts, EncryptionHelper encHelper)
{
string con = "some logic to get the connection string.";
_connection = new SqlConnection(con);
}
public int Execute(string query, object parameters = null)
{
return _connection.Execute(query, parameters);
}
}
IDisposable
实施:
using System;
public class MyConnectionString : IMyConnectionString, IDisposable
{
private readonly IDbConnection _connection;
public int ConnectionTimeout => _connection.ConnectionTimeout;
public string Database => _connection.Database;
public string ConnectionString
{
get => null;
set => _connection.ConnectionString = value;
}
public ConnectionState State => _connection.State;
public MyConnectionString(IOptions<ConnectionProviderOptions> connProvOpts, EncryptionHelper encHelper)
{
string con = "some logic to get the connection string.";
_connection = new SqlConnection(con);
}
public int Execute(string query, object parameters = null)
{
return _connection.Execute(query, parameters);
}
public void Dispose()
{
_connection.Dispose();
}
}
使用您自己的ISqlConnectionFactory
工厂:
public class MyConnectionString : IMyConnectionString, IDisposable
{
private readonly IDbConnection _connection;
private readonly ISqlConnectionFactory _factory;
public int ConnectionTimeout => _connection.ConnectionTimeout;
public string Database => _connection.Database;
public string ConnectionString
{
get => null;
set => _connection.ConnectionString = value;
}
public ConnectionState State => _connection.State;
public MyConnectionString(IOptions<ConnectionProviderOptions> connProvOpts, EncryptionHelper encHelper, ISqlConnectionFactory factory)
{
_factory = factory;
_connection = _factory.CreateConnection(connProvOpts, encHelper);
}
public int Execute(string query, object parameters = null)
{
return _connection.Execute(query, parameters);
}
}
public interface ISqlConnectionFactory
{
SqlConnection CreateConnection(IOptions<ConnectionProviderOptions> connProvOpts, EncryptionHelper encHelper);
}
public class SqlConnectionFactory : ISqlConnectionFactory
{
public SqlConnectionFactory()
{
// Maybe initialization?
}
public SqlConnection CreateConnection(IOptions<ConnectionProviderOptions> connProvOpts, EncryptionHelper encHelper)
{
string con = "some logic to get the connection string.";
_connection = new SqlConnection(con);
}
}
就个人而言,每次调用Connection
时,我都会创建并处理Execute
。这意味着在Execute
之外,您的连接将关闭,资源将被释放。