Внедрение строк соединения против IDbConnection

Каковы компромиссы для введения строк соединения против экземпляра IDbConnection?

Я использую StructureMap для добавления различных служб в мое приложение ASP.NET MVC, большинство из которых требуют доступа к базе данных для запросов LINQ-to-SQL. Впрыскивая IDbConnection кажется более тестируемым и более простым в настройке для IoC, чем универсальный параметр строки подключения, но меня беспокоит, что открытые соединения будут зависать, если я не укажу явное завершение соединения в using блок.

Есть ли какие-либо преимущества или недостатки пула соединений, о которых я должен знать?

Введенная строка подключения

using (var con = new SqlConnection(InjectedConnectionString))
{
    con.Execute("INSERT INTO Logs (...) VALUES (...)");
    using (var db = new MyDataContext(con))
    {
        var records = from p in db.Products
                      select p;
    }
}

Введенный IDbConnection

con.Execute("INSERT INTO Logs (...) VALUES (...)");
using (var db = new MyDataContext(InjectedConnection))
{
    var records = from p in db.Products
                  select p;
}

1 ответ

Решение

Особенностью любого умеренно сложного контейнера IoC (структурная карта) является возможность контролировать время жизни объектов. По умолчанию структура карты использует временное время жизни. Это означает, что он создает новый экземпляр для графа объекта. На практике это часто совпадает с каждым веб-запросом (если только вы не набросали свой код использованием container.GetInstance<T>()).

Используя структурную карту для внедрения ценных ресурсов, таких как соединения с базой данных, вы получаете контроль над тем, как долго они живут. Один ресурс можно (если вы выберете) повторно использовать в течение всего веб-запроса или создавать заново для каждого использования.

Кроме того, эти варианты (а также конфигурация) теперь выводятся в реестр вместо того, чтобы распространять их через ваш код. Если вам нужно изменить способ создания соединения, вам нужно искать только одно место. Классы с одной ответственностью всегда предпочтительнее.

Что касается вашего пула соединений, ни один контейнер IoC не будет задействован в таких деталях, как пул соединений. Они, однако, помогают с жизнями. Структура карты будет вызывать Dispose() на любом IDisposable объект (ну, это на самом деле интерпретатор, который вызывает его).

Редактировать: опять же, при пуле соединений, каждое время жизни имеет свои правила для того, как и когда объекты расположены. Transient полагается на CLR для удаления, однако HttpRequestScoped детерминистически удаляет объекты в конце каждого запроса. С помощью HttpRequestScoped не позволит вам увеличить количество подключений.

Другие вопросы по тегам