Много раз я спрашивал себя, что какой IoC контейнер подойдет для того или иного проекта. Их производительность — это только одна сторона медали. Полное сравнение производительности можно найти здесь. Другая сторона медали — простота и скорость обучения. Так что я решил сравнить несколько контейнеров с этой точки зрения и взял Autofac, Simple Injector, StructureMap, Ninject, Unity, Castle Windsor. На мой взгляд, это наиболее популярные IoC контейнеры. Вы можете найти некоторые из них в списке 20 лучших пакетов NuGet и также я добавил другие по своим предпочтениям. Лично мне очень нравится Autofac и во время работы над этой статьей я еще больше утвердился, что это лучший выбор в большинстве случаев. Здесь описываются основы IoC контейнеров, таких как конфигурация и регистрации компонентов. Есть мысль так же провести сравнение управления lifetime scope и продвинутых фитч. Примеры кода можно найти в репозитории LifetimeScopesExamples GitHub. Во время работы над статьей мне необходимо было обращаться к документации некоторых из IoC. К сожалению, не каждый IoC контейнер имеет хорошее описание и я был вынужден искать решение в Google. Таким образом получилось следующее резюме. Ссылки на документация, чтобы вы сами убедились: Здесь я не рассматриваю конфигурацию посредством XML. Все примеры описывают частые случаи конфигурирования IoC контейнеров посредством их интерфейса. Здесь вы можете найти следующее: Цель статьи состоит в том, чтобы привести рабочие примеры для каждого из случаев. Такие сложные сценарии, как параметризованные регистрации лежат за рамками этого текста. Для того чтобы проверить контейнеры IoC я создал простую модель. Есть несколько её модификаций, чтобы использовать property и method injection. Некоторые из IoC контейнеров требуют использования специальных атрибутов, чтобы инициализировать через свойства или методы. Я явно написал об этом в каждой секции. Тестовый сценарий создать контейнер и получает объект из него два раза, чтобы посмотреть, как работает их управление timelife scope. Об этом будет следующая статья. Конфигурация для этого не требует каких-либо специальных атрибутов или имен в своем базовом варианте. Некоторые IoC контейнеры требуют использования специальных атрибутов, которые помогают распознавать свойства для инициализации. Мне лично не нравится этот подход, поскольку модель объекта и IoC контейнер становится сильно связаны. Ninject требует использования атрибута , Unity требует атрибут . В то же время Castle Windsor не требует ничего, чтобы инициализировать свойства, т.к. у него это происходит по умолчанию. Данный подход, как и предыдущий, может помочь с циклическими ссылками. С другой стороны, это вносит еще один момент, который следует избегать. В нескольких словах API не дает никакого намека на то, что такая инициализация требуется для полноценного создания объекта. Тут чуть подробнее о temporal coupling. Тут так же некоторые контейнеры IoC требуют использования специальных атрибутов с теми же недостатками. Ninject требует атрибут  для методов. Unity требует использования атрибута . Все методы, помеченные такими атрибутами, будут выполнены в моментсоздания объекта контейнером. Большинство случаев в предыдущих секциях являются ни чем иным, как регистрация с помощью лямбда-выражений или делегатов. Такой способ регистрации поможет вам добавить некоторую логику в тот момент, когда создаются объекты, но это не динамический подход. Для динамики следует использовать параметризованную регистрацию, чтобы иметь возможность в run-time создавать разные реализации для одного компонента. или Ninject имеет различия между конфигурированием с помощью ToMethod и ToConstructor. В нескольких словах, когда вы используете ToContructor вы также можете использовать условия. Следующая конфигурация не будет работать для ToMethod. В некоторых случаях вам не нужно писать код конфигурации вообще. Общий сценарий выглядит следующим образом: сканирование assembly для поиска нужных типов, извлечение их интерфейсов и регистрация их в контейнере, как пара интерфейс-реализация. Это может быть полезно для очень больших проектов, но может быть сложно для разработчика незнакомово с проектом. Следует помнить несколько моментов. Autofac регистрирует все возможные варианты реализаций и сохраняет их во внутреннем массиве. В соответствии с документацией, он будет использовать самый последний вариант для резолва по умолчанию. Simple Injector не имеет готовых методов для автоматической регистрации. Вы должны сделать это вручную (пример ниже). StructureMap и Unity требуют public классы имплементаций, т.к. их сканеры другие не видят. Ninject требует дополнительный NuGet пакет Ninject.Extensions.Conventions. И он так же требует public-классы имплементаций. Модули могут помочь вам разделить вашу конфигурацию. Вы можете сгруппировать их по контексту (доступ к данным, бизнес-объекты) или по назначению (production, test). Некоторые из контейнеров IoC может сканировать сборки в поисках своих модулей. Тут я описал основной способ их использования. В следующих текстах рассмотрю lifetime scope management и advanced features. Software Developer