用IoC(Castle Windsor)替换以下代码

时间:2010-09-10 10:58:06

标签: c# castle-windsor ioc-container

如果我有下面的代码,那么用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();
           }
       }
    }
}

2 个答案:

答案 0 :(得分:1)

我使用过IoC而不是Castle,虽然它们都很相似,所以这就是我对此的看法。

我认为你走在正确的轨道上 - 尽管我可能会使用单独的工厂进行连接和命令,或者事实上将连接打开和命令运行到另一个类,因此存储库不必知道这个细节。只需在类的构造函数中包含IDatabase,以便注入它(如果使用基于属性的注入,则使用属性)。使用IDbConnection和IDbCommand替换代码中的SqlConnection和SqlCommand。

更新

他们继承/实现IDisposable,因此您可以使用using语句。抱歉我的错误。

答案 1 :(得分:1)

一般的方法对我来说似乎很好,虽然我不会试图模仿IDbConnectionIDbCommand接口,因为这可能很复杂,更重要的是不会告诉你代码是否有效如预期的那样。

它允许您更改您使用的数据库,因此您可以使用Sqlite之类的东西进行单元测试,然后在集成测试期间针对您的生产数据库测试代码。

您还可以将连接字符串移动到IDatabase抽象中,这将简化客户端。