Замена следующего кода на IoC (Castle Windsor) - PullRequest
4 голосов
/ 10 сентября 2010

Если бы у меня был приведенный ниже код, каковы наилучшие рекомендации / рекомендации по его замене на 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 ]

1 голос
/ 10 сентября 2010

Общий подход кажется мне подходящим, хотя я не буду пытаться насмехаться над интерфейсами IDbConnection и IDbCommand, поскольку это может быть сложно, и, что более важно, не скажет вам, работает ли код как задумано.

Это позволит вам изменить используемую базу данных, чтобы вы могли использовать что-то вроде Sqlite для модульного тестирования, а затем проверять код на вашей производственной базе данных во время интеграционного тестирования.

Вы также можете переместить строку подключения в абстракцию IDatabase, которая упростит клиентам.

1 голос
/ 10 сентября 2010

Я использовал IoC, но не Castle, хотя все они похожи, поэтому вот мой улов:

Я думаю, что вы на правильном пути - хотя я мог бы использовать отдельную фабрику для подключения и командыфактически оставьте открытие соединения и выполнение команды другим классом, чтобы хранилище не должно было знать эту деталь.Просто добавьте IDatabase в конструктор вашего класса, чтобы он был внедрен (или используйте свойство, если вы используете инъекцию на основе свойств).Замените SqlConnection и SqlCommand в своем коде на IDbConnection и IDbCommand.

ОБНОВЛЕНИЕ

Они наследуют / реализуют IDisposable, поэтому вы МОЖЕТЕ использовать оператор using.Извините за мою ошибку.

...