IoC и .NET framework

#c# #.net #ioc-container

#c# #.net #ioc-контейнер

Вопрос:

Я хочу знать, какова наилучшая практика использования шаблона IoC при работе с .NET

Например, должен ли я создать SqlConnection / OracleConnection или любого другого поставщика через контейнер IoC или с помощью простого ключевого слова new?

Имеет ли какое-либо значение разделение моего класса на конкретные типы поставщиков (в том числе, когда я хочу использовать только один тип поставщика)?

Ответ №1:

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

DI также позволяет вам легче повторно использовать код из одного проекта в другой, поскольку это делает зависимости между различными частями более явными.

Тем не менее, я никогда не использовал контейнер IOC и никогда не видел необходимости в нем, поэтому я не могу комментировать этот аспект вопроса.

Но вам определенно следует максимально удалить неявные зависимости из вашего кода, просто чтобы сохранить код повторно используемым, поддерживаемым и корректным.

Комментарии:

1. Ну, вы меня поймали на слове «DI — это скорее разделение, чем проверка вашего провайдера на будущее». Очень жаль, что у вас нет большего опыта работы с DI, который вы могли бы предложить. Но все равно 1.

Ответ №2:

Вводить SqlConnection или a IDbConnection было бы довольно бесполезно, потому что DbConnection — это непрочная абстракция. Вы можете использовать его только для вызова хранимых процедур или запросов простого SELECT * FROM VIEW типа. Любые более сложные запросы будут отличаться для каждого диалекта SQL.

У вас будет лучшее изменение успеха, если вы скроете само соединение за абстракцией более высокого уровня, такой как IUserRepository или какой-либо другой. Реализацией этого интерфейса по умолчанию, вероятно, будет a, SqlUserRepository который будет взаимодействовать с MS SQL Server, или a, OracleUserRepository который взаимодействует с Oracle.

Еще лучше было бы отойти от низкого уровня ADO.NET DbConnection API и перейдите на O / RM, такой как LINQ to SQL или Entity Framework. Тогда у вас обычно был бы LinqToSqlUserRepository .

Обратите внимание, что в этом случае я все еще говорю о XXXUserRepository . Интерфейс по-прежнему не изменился. Другими словами: IUserRepository это не дырявая абстракция. Вы можете заменить этот интерфейс для модульного тестирования, в то время как это вряд ли возможно при использовании SqlConnection .

Комментарии:

1. Я знаю о репозиториях и orm 🙂 Я только что написал очень простой пример использования 🙂 В любом случае спасибо

2. 1 за то, что «Внедрение SqlConnection или IDbConnection было бы довольно бесполезным, потому что DbConnection — это непрочная абстракция», очень верно.

3. Ребята, что означает «дырявая абстракция»?

4. @Davita: Ты пробовал гуглить? В Википедии есть (конечно) определение: en.wikipedia.org/wiki/Leaky_abstraction .

Ответ №3:

Это может иметь значение для модульного тестирования, если вы используете IDbConnection и все другие классы вместо конкретных классов.

Помимо IOC и тому подобного, я на самом деле несколько раз использовал DbFactoryProvider (еще немного информации) для создания своих подключений и других объектов, связанных с БД, и считывал поставщика через строку ConnectionString.

Основная проблема с БД заключается в том, что обычно вы не можете использовать с базой данных только ANSI-SQL, поэтому, пока вы не связаны с конкретными классами, ваш sql нельзя переносить. (ограничение ввода-вывода в MySQL или превышение и разделение в Sql Server).

О DI / IOC с другими материалами, не связанными с БД, здорово отделять ваши классы и удалять зависимости, и это помогает при модульном тестировании, скажем, когда у вас есть сервис, с которым вы работаете, это полезно даже тогда, когда вы не участвуете в модульном тестировании, когда вы работаете с сервисом, а другая команда все еще разрабатывает сервис, вы можете создать поддельный сервис, который в основном решает ваши проблемы (не все), чтобы вы могли работать с чем-то, прежде чем станет доступен реальный сервис.

Примеров намного больше, но работа со службами (репозиторий БД / веб / авторизация / что угодно) — это первое, самое простое добавленное значение.

Ответ №4:

IOC существует для того, чтобы, хотя вы хотите использовать провайдер одного типа, в реальности когда-нибудь что-то изменится, и вам может понадобиться дополнительный адаптер, поэтому лучше использовать IoC вместо создания объекта с использованием ключевого слова new. IoC обеспечивает гибкость, позволяющую со временем что-то менять (по мере изменения требований).

Комментарии:

1. Что ж, если я когда-нибудь захочу использовать другой тип, я думаю, MEF больше подходит для этой цели. Поправьте меня, если я ошибаюсь. Разве использование IoC в данном конкретном случае не повышает качество кода за счет ослабления связи кода?

2. Да, это так, вот почему он гибкий… Я не сказал ничего, что противоречило бы вашему утверждению, и я не поддерживаю его открыто, но это не делает то, что я говорю, неправильным…

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

Ответ №5:

Было бы хорошей практикой использовать IoC даже для .СЕТЕВЫЕ классы. Это позволит привязать ваш код только к интерфейсу или базовому классу, если он доступен. И не только это, но вы можете использовать свою IoC framework для указания аргументов конструктора. Это может быть полезно для строк подключения в SqlConnection.

Я должен также упомянуть, что использование IoC и написание кода только для интерфейса значительно упростит модульное тестирование. Это особенно верно при работе с подключениями к БД.