2016-12-29 15 views
1

Является ли конвенция на основе сборки хорошей идеей? В настоящее время у меня есть что-то вродеПроизводительность сканирования контейнеров IOC

foreach(var type in assembly) 
{ 
    if(isRepository(type)) 
     registerAsRepository(type); 
} 

Это займет больше 1 секунды при запуске. Интересно, не было бы лучше просто зарегистрировать все типы вручную и реализовать какое-то «тестирование регистрации» в тестах, а не во время выполнения?

+0

Пожалуйста, прочтите [это] (http://blog.ploeh.dk/2012/11/06/WhentouseaDIContainer/) и [это] (https://simpleinjector.org/blog/2015/12/when-should -вы использование-а-контейнер /). – Steven

+0

Хорошая точка для конвенции. Однако мне не нравится тот факт, что соглашения должны обрабатывать все типы во всех сборках во время выполнения, и я не могу легко прекомпретировать его. Также становится все труднее, когда меняются соглашения, например, у вас есть полный текстовый поиск IQueryHandler, который работает на mysql, но вдруг у вас есть служба sphinx, которая делает то же самое. Или вы хотите обменять службы на основе конфигурации. Или у вас есть два набора IQueryHandler, один для oracle и еще один для mysql (в одной сборке). Что тогда? Регистраторы autofac OOTB не будут обрабатывать эти соглашения. – user2029276

+1

Я бы советовал не использовать контейнер вообще. Контейнер является дополнительным инструментом. Он становится действительно мощным, когда вы делаете соглашение по настройке и пакетной регистрации. Если ваше приложение достаточно мало, выполнение [Pure DI] (http://blog.ploeh.dk/2014/06/10/pure-di/) может быть намного более ценным. – Steven

ответ

0

Мне нравится этот вопрос. Это так просто, но затрагивает так много аспектов проблемного пространства.

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

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

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

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

Тогда возникает вопрос архитектуры. Контейнеры являются острым инструментом и предоставляют вам ряд опций, несмотря на простоту их API. Все примеры, которые вы даете в комментариях, могут быть легко обработаны с помощью комбинации регистрации по соглашению, явной регистрации типа и некоторой конфигурации. Я хотел бы направить вас к документации по вашему контейнеру по поводу специфики, но это стандартный сценарий, и все зрелые контейнеры справляются с этим очень хорошо и с более чем приемлемой производительностью.

+0

Спасибо за ответ. Очевидно, что 1 с времени запуска - это просто стоимость ди, мне просто грустно, что новый проект начинается медленнее, чем старый.). Не могли бы вы привести пример такой регистрации по соглашению, где вы хотите зарегистрировать обработчики только для MySql, а не для Oracle в одной сборке? (Я имею в виду, что они отличаются только зависимостями) – user2029276