Ninject 的 Dapper 一次性实例
Dapper disposable instance with Ninject
我想使用 Ninject 绑定数据库连接实例并在线程范围内使用它,以便在需要进行查询时跳过重复输入 using { var cn = new DbConnectionFactory() } [..]
。
我添加了绑定:
IOC.Kernel.Bind<IDbConnection>().ToMethod(ctx =>
{
using (var cn = new DbConnectionFactory())
{
return cn.GetConnection();
}
}).InThreadScope();
数据库工厂class:
public class DbConnectionFactory : IDisposable
{
private IDbConnection _connection;
public DbConnectionFactory()
{
_connection = new SQLiteConnection("Data Source=mydb.sqlite;Version=3;");
_connection.Open();
}
public IDbConnection GetConnection() => _connection;
public void Dispose()
{
_connection.Close();
}
}
现在,一切正常。每个线程正在创建一个数据库连接,但是,连接正在关闭但未被释放!
所以当我修改我的 Dispose
方法时:
public void Dispose()
{
_connection.Close();
_connection.Dispose();
}
连接似乎不再正常工作,访问时抛出异常:ObjectDisposedException
对象不再可访问。
问题是:如何在 Ninject 中正确绑定和处理连接?
请注意,我不能使用 .InRequestScope(),因为这不是 Web 应用程序。
对于 Ninject 和其他 IoC 容器,容器有责任在一次性对象上调用 Dispose
。不幸的是,在您的实施中,您自己调用了 Dispose
- 并且调用不正确。
using (var cn = new DbConnectionFactory())
{
return cn.GetConnection();
}
此代码创建 DbConnectionFactory
并创建数据库连接。然后(由于 using
)它调用 cn.Dispose
。然后,您的实施会处理您 刚刚 创建的新连接。
有多种方法可以解决这个问题,但我建议您首先改变的是:
public class DbConnectionFactory
{
public IDbConnection GetConnection()
{
var connection = new SQLiteConnection("Data Source=mydb.sqlite;Version=3;");
connection.Open();
return connection;
}
}
然后:
IOC.Kernel.Bind<IDbConnection>().ToMethod(ctx =>
{
var cn = new DbConnectionFactory();
return cn.GetConnection();
}).InThreadScope();
然后,根据 docs,当底层 Thread
被垃圾回收时,数据库连接将自动 Dispose
d。
我想使用 Ninject 绑定数据库连接实例并在线程范围内使用它,以便在需要进行查询时跳过重复输入 using { var cn = new DbConnectionFactory() } [..]
。
我添加了绑定:
IOC.Kernel.Bind<IDbConnection>().ToMethod(ctx =>
{
using (var cn = new DbConnectionFactory())
{
return cn.GetConnection();
}
}).InThreadScope();
数据库工厂class:
public class DbConnectionFactory : IDisposable
{
private IDbConnection _connection;
public DbConnectionFactory()
{
_connection = new SQLiteConnection("Data Source=mydb.sqlite;Version=3;");
_connection.Open();
}
public IDbConnection GetConnection() => _connection;
public void Dispose()
{
_connection.Close();
}
}
现在,一切正常。每个线程正在创建一个数据库连接,但是,连接正在关闭但未被释放!
所以当我修改我的 Dispose
方法时:
public void Dispose()
{
_connection.Close();
_connection.Dispose();
}
连接似乎不再正常工作,访问时抛出异常:ObjectDisposedException
对象不再可访问。
问题是:如何在 Ninject 中正确绑定和处理连接?
请注意,我不能使用 .InRequestScope(),因为这不是 Web 应用程序。
对于 Ninject 和其他 IoC 容器,容器有责任在一次性对象上调用 Dispose
。不幸的是,在您的实施中,您自己调用了 Dispose
- 并且调用不正确。
using (var cn = new DbConnectionFactory())
{
return cn.GetConnection();
}
此代码创建 DbConnectionFactory
并创建数据库连接。然后(由于 using
)它调用 cn.Dispose
。然后,您的实施会处理您 刚刚 创建的新连接。
有多种方法可以解决这个问题,但我建议您首先改变的是:
public class DbConnectionFactory
{
public IDbConnection GetConnection()
{
var connection = new SQLiteConnection("Data Source=mydb.sqlite;Version=3;");
connection.Open();
return connection;
}
}
然后:
IOC.Kernel.Bind<IDbConnection>().ToMethod(ctx =>
{
var cn = new DbConnectionFactory();
return cn.GetConnection();
}).InThreadScope();
然后,根据 docs,当底层 Thread
被垃圾回收时,数据库连接将自动 Dispose
d。