Замок Виндзор есть ли минусы?
Я изучал проект Castle и, в частности, Виндзор. Я был очень впечатлен тем, что возможно с этой технологией, и преимущества такой слабосвязанной системы, безусловно, очевидны. Единственное, в чём я не уверен - есть ли у этого метода какие-либо недостатки, особенно в asp.net? например, хиты производительности и т. д.
Я пытаюсь сделать так, чтобы преимущества этого подхода были видны моим коллегам-разработчикам, и меня ждут следующие отклики:
Это использует отражение, и каждый раз, когда объект вызывается из контейнера, отражение должно использоваться, чтобы производительность была ужасной. (Это так? Использует ли он отражение при каждом вызове?)
Если я полагаюсь на интерфейсы; Как мне работать с объектами, которые имеют дополнительные методы и свойства, которые были добавлены в класс? (через наследство)
7 ответов
Чтобы ответить на ваши вопросы:
- Это использует отражение, и каждый раз, когда объект вызывается из контейнера, отражение должно использоваться, чтобы производительность была ужасной. (Это так? Использует ли он отражение при каждом вызове?)
- Нет. В большинстве случаев при регистрации компонента используется небольшое отражение. Он также может использовать отражение при создании типа прокси, когда вы впервые запрашиваете компонент из контейнера.
- Если я полагаюсь на интерфейсы; Как мне работать с объектами, которые имеют дополнительные методы и свойства, которые были добавлены в класс? (через наследство)
- Все дело в дизайне. Вы не хотите, чтобы каждый объект создавался контейнером. Вы используете его в первую очередь для служебных зависимостей. В этом случае вас не волнует, какой тип на самом деле скрывается за интерфейсом (в этом весь смысл, не так ли?).
У вас также могут быть компоненты класса, но у них есть ограничения, и вы должны знать о них (например, вы не можете перехватывать вызовы не виртуальных методов). Я считаю Виндзор самым зрелым и лучше всего подходящим для моего стиля разработки контейнера из всех.
Помимо этого, Performance, я не слышал о проекте, который должен был отказаться от контейнера зависимостей из-за неприемлемой производительности. Виндзор действительно хорош в этом, и он кеширует результаты длительных операций, так что вам не придется платить цену дважды. Вы можете найти графики в Интернете, сравнивая скорость многих контейнеров IoC. Об этом следует отметить две вещи: все контейнеры действительно быстрые. Не думайте, что тот факт, что другие контейнеры на этих графиках работают быстрее, чем Виндзор, означает, что они лучше. Виндзор делает много вещей для вас, чего не делают другие контейнеры.
Я использовал контейнеры IoC (Spring.NET и StructureMap) в нескольких производственных приложениях при высокой нагрузке (не Facebook/MySpace, но достаточно, чтобы выделить несколько серверов).
По моему опыту, даже до того, как я начал использовать IoC, наибольшую обеспокоенность вызывали базы данных и взаимодействие с базой данных - оптимизация запросов, индексов, использование кэширования 2-го уровня и т. Д.
Если у вас есть база данных, связанная с вашим приложением, то, что бы ни повлияло на производительность Windsor или любого другого контейнера, будет настолько малым по сравнению с циклом обработки БД.
Это похоже на людей, которые сравнивают снижение производительности оператора new() с Activator.CreateInstance() при 1-10 мс, когда одиночная поездка в оба конца БД обычно на порядок дороже.
Я бы посоветовал вам не беспокоиться о мелочах и сосредоточиться на больших вещах.
Кроме того, я хотел бы посоветовать вам взглянуть на StructureMap, так как я считаю, что он обладает гораздо большей функциональностью, чем Windsor, и не имеет многих недостатков Windsor (т. Е. Удерживает ссылки и требует их публикации и т. Д.).,
Одна проблема с Castle Windsor, с которой я столкнулся, заключается в том, что он не может работать в Medium Trust (без перекомпиляции, которую я не смог сделать). Поэтому мне нужно было переключиться с Виндзора на Unity.
Что касается производительности DI/IoC - я считаю, что снижение производительности невелико, особенно если учитывать его мощность.
Кстати: если вы начинаете с DI/IoC, вы должны прочитать эту статью MSDN.
Значительные затраты на запуск, почти не влияют на производительность во время работы (конечно же, не нужно учитывать вызовы - все компилируется во время создания экземпляра). Виндзор немного тяжел, но при правильном управлении временем жизни проблем не должно быть.
Более важным недостатком является то, что проблемы интеграции не обнаруживаются во время сборки, а некоторые даже не при запуске. Без тщательного отслеживания версий всех модулей и непрерывного тестирования всей системы легко попасть в неприятности. Здесь помогает рефлексия, поэтому Windsor лучше в этом аспекте, чем многие другие DI-фреймворки.
Единственное исключение, при котором производительность контейнера IoC в моем опыте неприемлема, - это попытка интегрировать / обернуть контейнер IoC в качестве IServiceProvider для использования в ComponentModel - один из распространенных примеров этого был при создании собственного размещенного конструктора winforms (обычно для создать какой-то собственный конструктор, т. е. рабочий процесс / блок-схему и т. д.)
Из-за того, как ведут себя некоторые компоненты winforms, особенно во время разработки, стоимость разрешения компонента физически заставит мышь "заикаться" при перетаскивании, потому что инфраструктура может делать до 30000 вызовов разрешения службы в секунду - это больше хотя я думаю, что это отражение плохой практики кодирования в самих компонентах, или, по крайней мере, из-за предположений о быстрой / простой реализации поставщиков услуг.
На практике я никогда не находил проблемы с разрешением компонентов даже в сильно загруженных коммерческих приложениях.
Что касается производительности, см. Эти статьи:
- http://www.codinginstinct.com/2008/04/ioc-container-benchmark-unity-windsor.html
- http://www.codinginstinct.com/2008/04/ioc-benchmark-revisited-ninject.html
- http://www.codinginstinct.com/2008/05/ioc-container-benchmark-rerevisted.html
Но помните, что некоторые из этих контейнеров имеют более новые (и, возможно, более быстрые) версии - особенно Unity.
- Это использует отражение, и каждый раз, когда объект вызывается из контейнера, отражение должно использоваться, чтобы производительность была ужасной. (Это так? Использует ли он отражение при каждом вызове?)
Насколько известно, все хорошие контейнеры (включая замок Виндзор) используют отражение для создания новых экземпляров. Однако это улучшение производительности. Это для сравнения с Activator.CreateInstance, который намного медленнее. Некоторые другие контейнеры довольно быстрые и могут конкурировать с новым оператором. Смотрите сравнительный тест здесь. Замок Виндзор не из высокопроизводительных, но скорость не так важна. Когда дело доходит до использования IoC в приложении. 90% ваших классов должны быть установлены как одиночные, и это означает, что они работают только при запуске вашего приложения.
- Если я полагаюсь на интерфейсы; Как мне работать с объектами, которые имеют дополнительные методы и свойства, которые были добавлены в класс? (через наследство)
Попробуйте этот урок и этот урок. Это покажет ответ на ваш вопрос. Если вы хотите избежать проблем с дизайном и простым в обслуживании программным обеспечением, я настоятельно рекомендую перейти на SOLID