代码之家  ›  专栏  ›  技术社区  ›  Paul Hadfield

用IoC(温莎城堡)替换下列代码

  •  4
  • Paul Hadfield  · 技术社区  · 14 年前

    注意:使用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();
               }
           }
        }
    }
    

    我相信至少会有一些选择,但由于我们刚刚开始与国际奥委会合作,我不相信他们以后不会给我们带来问题和/或与国际奥委会的理念背道而驰。我喜欢的方法是太修改方法如下,有人能突出潜在的问题吗?

    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 回复  |  直到 14 年前
        1
  •  1
  •   Aliostad    14 年前

    我用过IoC,但没有用过Castle,尽管它们都很相似,所以这里是我对这个的理解。

    我认为您的思路是正确的——尽管我可能会对连接和命令使用一个单独的工厂,或者实际上将打开的连接和运行的命令留给另一个类,这样存储库就不必知道这个细节。只需在类的构造函数中设置IDatabase,以便注入它(如果使用基于属性的注入,则使用属性)。将代码中的SqlConnection和SqlCommand替换为IDbConnection和IDbCommand。

    它们确实继承/实现IDisposable,因此您可以使用using语句。对不起,我错了。

        2
  •  1
  •   Lee    14 年前

    一般的方法对我来说似乎很好,尽管我不会试图嘲笑 IDbConnection IDbCommand

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

    您还可以将连接字符串移动到 IDatabase 简化客户机的抽象。