我所拥有的:
public interface IRepository
{
IDisposable CreateConnection();
User GetUser();
//other methods, doesnt matter
}
public class Repository
{
private SqlConnection _connection;
IDisposable CreateConnection()
{
_connection = new SqlConnection();
_connection.Open();
return _connection;
}
User GetUser()
{
//using _connection gets User from Database
//assumes _connection is not null and open
}
//other methods, doesnt matter
}
这使得使用IRepository的类可以轻松进行测试并且容易与IoC容器集成。然而,使用该类的人在调用从数据库获取数据的任何方法之前必须调用CreateConnection,否则会抛出异常。这本身是有好处的——我们不希望在应用程序中有持久性连接。因此,使用这个类,我像这样实现。
using(_repository.CreateConnection())
{
var user = _repository.GetUser();
//do something with user
}
很遗憾,这不是一个好的解决方案,因为使用这个类的人(包括我自己!)经常会忘记在调用从数据库获取信息的方法之前调用_repository.CreateConnection()
。
为了解决这个问题,我看了 Mark Seemann 的博客文章 SUT Double,他以正确的方式实现了 Repository 模式。不幸的是,他使 Repository 实现了 IDisposable 接口,这意味着我不能简单地通过 IoC 和 DI 将其注入到类中并在使用后继续使用,因为在使用一次后它就会被释放。他每个请求使用一次,并利用 ASP.NET WebApi 的能力在请求处理完成后将其清除。但我有我的类实例一直在工作,它们需要使用 Repository。
在这里最好的解决方案是什么?我应该使用某种工厂来给我提供 IDisposable IRepository 吗?那样会容易进行测试吗?