如果我有下面的代码,用IoC替换它的最佳实践/设计考虑(我们希望使用Castle Windsor).由于“using”语句负责创建连接对象,因此无法将其直接注入构造函数或方法中.注意:使用SQL连接似乎是一个干净的例子,这里的主要好处是模拟/单元测试
public void CustomerRespository
{
....
public void Save(Customer customer)
{
using (var cn = new SqlConnection(connectionString))
{
using (var cm = new SqlCommand(commandString, cn))
{
....
cn.Open();
cm.ExecuteNonQuery();
}
}
}
}
我相信至少会有一些选择,但是当我们刚开始使用IoC时,我不相信它们不会在以后引起我们的问题和/或面对IoC概念.我最喜欢的方法是修改方法如下,任何人都可以突出它的潜在问题吗?
public interface IDatabase
{
IDbConnection Connection(string connectionString);
IDbCommand Command(string text, IDbConnection conn);
}
public class SqlDB : IDatabase
{
IDbConnection Connection(string connectionString)
{ return new SqlConnection(connectionString); }
IDbCommand Command(string text, IDbConnection conn)
{ return new SqlCommand(text, conn); }
}
public interface ICustomerRespository
{
void Save(Customer customer)
}
public class CustomerRespository : ICustomerRespository
{
public IDatabase DB{get; private set;}
public CustomerRespository( IDatabase db)
{
DB = db;
}
....
public void Save(Customer customer)
{
using (var cn = DB.Connection(connectionString))
{
using (var cm = DB.Command(commandString, cn))
{
....
cn.Open();
cm.ExecuteNonQuery();
}
}
}
}
最佳答案 虽然它们都很相似所以我使用过IoC而不是Castle,所以这里是我的关注点.
我认为你走在正确的轨道上 – 虽然我可能会使用一个单独的工厂进行连接和命令,或者事实上将连接打开和命令运行到另一个类,因此存储库不必知道这个细节.只需在类的构造函数中包含IDatabase,以便注入它(如果使用基于属性的注入,则使用属性).使用IDbConnection和IDbCommand替换代码中的SqlConnection和SqlCommand.
UPDATE
它们继承/实现IDisposable,因此您可以使用using语句.对不起,我错了.