IOC Design Resources - PullRequest
       11

IOC Design Resources

6 голосов
/ 19 ноября 2008

Я довольно много искал по этому вопросу, и мне не повезло найти что-то связное. Я относительно новый разработчик и только начал свою первую профессиональную карьеру. Я знаю, что мне есть чему поучиться даже в сфере основ. На основе прослушивания PodCasts, чтения блогов, газет и т. Д .; Я пришел к выводу, что правильное разделение интересов, IOC, Dependency Injection при проектировании и создании программного обеспечения кажется правильным решением. Я получаю концепции на ОЧЕНЬ высоком уровне и хочу как можно больше приблизиться к тому, что я делаю с этим.

Итак, вот в чем дело. КАК, черт возьми, я так спроектирую вещи? Я работаю в команде, унаследовавшей веб-продукт, который очень тесно связан, очень плохо документирован и, как правило, не прост в обслуживании. Эврионе, похоже, нравится идея удалить часть этой пары. Им нравится идея разработки автоматических тестов (что из того, что я прочитал, легче сделать со слабосвязанными компонентами). Кажется, никто не знает, как это сделать. Я готов нанести удар, но мне нужно руководство. Все, что я нашел, кажется, говорит об этом материале на очень высоком уровне или, наоборот, фокусируется только на небольшой части целого. Я хотел бы получить руководство по книге, или серии учебных пособий, или видео, или что-то, что берет некоторый реальный пример и показывает вам, как применять эти принципы. В идеале, я бы очень хотел увидеть что-то, что говорит ... "Возьмите, к примеру, это приложение для ввода заказов. Именно так большинство людей собирают его сегодня, используя стандартные наборы данных ADO.NET, бла ... бла ... бла. СЕЙЧАС! Если мы применяем принципы МОК, чтобы сделать этот слабо связанный проект, вот что вы делаете по-другому. Вот ПОЧЕМУ вы делаете это таким образом, и вот что вы должны учитывать, когда пытаетесь достичь этого. "

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

Спасибо всем за потраченное время.

Steve

Ответы [ 6 ]

4 голосов
/ 25 ноября 2008

Я был в такой же ситуации, и я купил эти две книги

(PDF-версия для распечатки) http://www.manning.com/osherove/ а также http://www.manning.com/prasanna/

4 голосов
/ 19 ноября 2008

Вы обязательно должны проверить скриншоты IoC на dimecasts.net . Они очень просты и помогут вам понять некоторые концепции.

3 голосов
/ 23 ноября 2008

Я бы посоветовал вам прочитать книгу Джеймса Ковача, упомянутую в этом блоге Один особенно острый для вашей ситуации. Это «Эффективная работа с устаревшим кодом». У этого есть очень хорошие объяснения понятий рефакторинга. Также приводятся примеры этой концепции, которая, хотя в C #, Java и C ++ очень проста для понимания.

2 голосов
/ 19 ноября 2008

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

Требуется * маленький * проект с открытым исходным кодом, c # с расширенным модульным тестированием

Я рекомендую посмотреть на CarTrackr имеет широкий спектр технологий .Net что разработчик должен быть знаком с (Unity, MVC особенно) и имеет обширное модульное тестирование. Проект достаточно прост, чтобы переварить 1 сидя, но достаточно сложный, чтобы на самом деле быть больше, чем проверка концепции. URL их кодекса я сидела http://www.codeplex.com/CarTrackr

2 голосов
/ 19 ноября 2008

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

По сути, у нас есть то, что мы называем ServiceContainer, объектом. Его всегда есть глобальный экземпляр, одиночная копия, если хотите, статическая, и, следовательно, в веб-приложении, совместно используемая всеми пользователями в домене приложения.

Контейнер ServiceContainer содержит правила. В правилах говорится что-то вроде Если кто-то запрашивает объект типа XYZ, вот как вы его предоставите .

Например, правило может состоять в том, что для того, чтобы некоторый код получил объект, который реализует IDbConnection, контейнер создавал, настраивал и возвращал новый объект SqlConnection.

Таким образом, рассматриваемый код не знает и не заботится о том, что он использует объект SqlConnection, а не объект OleDbConnection.

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

Теперь, код , о котором идет речь, здесь нужно будет указать контейнер, который он должен использовать, и, следовательно, правила. Это означает, что с точки зрения модульного тестирования я мог бы создать новый экземпляр ServiceContainer, записать в него новые правила для целей тестирования и попросить код выполнить свою работу. В конечном счете, коду потребовалось бы выполнить некоторый SQl (в данном случае), и вместо того, чтобы общаться с реальной базой данных, он вызвал бы мою тестовую реализацию IDbConnection и IDbCommand и таким образом дал бы мне возможность проверить, что все работает.

Что еще более важно, это дает мне возможность вернуть обратно фиктивные данные, соответствующие тесту, без необходимости макетирования всей базы данных.

Теперь, для части инъекция , в нашем случае мы можем попросить контейнер предоставить нам объекты, которые должны быть сконструированы, которые опираются на другие объекты.

Например, допустим, у нас есть интерфейс IDataAccessLayer и реализация MSSQLDataAccessLayer.

Хотя интерфейс не дает нам внешнего признака того, что он ведет какую-либо запись, фактическая реализация здесь должна иметь место для регистрации всего SQL, который он выполняет. Таким образом, конструктор для класса может выглядеть так:

public MSSQLDataAccessLayer(ILogger logger) { ... }

В объекте ServiceContainer мы зарегистрировали следующие правила (это наш синтаксис, вы нигде больше этого не найдете, но ему должно быть достаточно легко следовать):

ServiceContainer.Global.RegisterFactory<ILogger, FileLogger>()
    .FactoryScoped()
    .WithParameters(
        new Parameter("directory", @"C:\Temp")
    );
ServiceContainer.Global.RegisterFactory<IDataAccessLayer, MSSQLDataAccessLayer>()
    .FactoryScoped();

FactoryScoped означает, что каждый раз, когда я запрашиваю контейнер для объекта, я получаю новый.

Правила, если я напишу их по-английски, будут такими:

  • Если кому-то нужна реализация ILogger, создайте новый объект FileLogger, возьмите конструктор, которому нужен параметр "directory", и используйте этот конструктор, передавая "C: \ Temp" в качестве аргумента
  • Если кому-то нужна реализация IDataAccessLayer, создайте новый MSSQLDataAccessLayer

Обратите внимание, что я говорил ранее, что конструктор MSSQLDataAccessLayer принимает ILogger, но я не указал здесь никаких параметров? Это дает мне следующий код для получения доступа к объекту уровня доступа:

IDataAccessLayer dal = ServiceContainer.Global.Resolve<IDataAccessLayer>();

Что происходит сейчас, так это то, что объект контейнера выясняет, что это объект MSSQLDataAccessLayer и что у него есть конструктор. Этому конструктору требуется объект ILogger, но вот, контейнер знает, как его создать. Контейнер, таким образом, создаст новый объект FileLogger и передаст его конструктору объекта MSSQLDataAccessLayer без вывода сообщений.

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

В целях модульного тестирования я могу переписать правила, чтобы предоставить свой собственный объект-регистратор, который просто хранит записанный текст в памяти, что позволяет мне легко проверить, действительно ли регистрировалось то, что, как я ожидал, регистрируемый код, без необходимости прочитайте файл позже.

Правила дают нам много возможностей относительно того, как на самом деле предоставлять экземпляры объектов:

  • Из делегата / метода, что означает, что мы можем сделать всю магию создания зависимых объектов самостоятельно, если мы хотим
  • Автоматически из конструктора (либо автоматически выясняется, какой из них использовать, либо мы можем предоставить достаточно фиктивных параметров по именам / типам, чтобы выбрать один)
  • Или мы можем предоставить существующий экземпляр контейнеру (тогда он будет похож на одиночный)

Мы посмотрели на autofac , прежде чем придумать свой собственный, в основном мы просто посмотрели на вики, показывающие примеры синтаксиса вызовов, а затем сели и написали нашу собственную систему, которая делала то, что нам нужно.

1 голос
/ 13 января 2009

Эта статья Ayende - лучшее введение в IoC, которое я когда-либо видел.

...