Что означает атрибут forceBinFolderScan в файле EPiServerFramework.config?
Я готовился к экзамену EPiServer и прочитал эту статью об инициализации EPiServer: http://world.episerver.com/Documentation/Items/Tech-Notes/EPiServer-CMS-6/EPiServer-CMS-60/Initialization/
Он описывает, как настроить инициализацию для ограничения сборок, которые будут сканироваться во время запуска, но есть упомянутый атрибут forceBinFolderScan, который не описан. Примеры всегда имеют значение true.
Я также нашел другую статью, которая описывает, как улучшить время запуска сайта EPiServer: http://world.episerver.com/Blogs/Alexander-Haneng/Dates/2011/12/Starting-CMS-6-R2-sites-faster-after-build/
Автор говорит, чтобы изменить этот атрибут на false, но не объясняет, что это значит. Останавливает ли установка значения false значение сканирования сборок вообще или сканирует их только при определенных условиях?
У меня довольно большой сайт, и загрузка занимает несколько минут. У меня много сборок в папке bin, поэтому я хотел ограничить сканирование только теми, которые содержат некоторые модули инициализации или плагины.
4 ответа
Из-за алгоритмов оптимизации системы сборки приложений и запуска приложений Asp.Net все сборки могут не загружаться в домен приложения. Это может скрыть некоторые сборки от системы инициализации EPiServer, которая выполняется во время запуска приложения. Чтобы избежать этого - EPiServer позволяет вам установить это forceBinFolderScan
флаг для принудительного сканирования бина / папки (и проверяющей папки для v7) сканирования сборок. Если флаг установлен в значение true - EPiServer не запрашивает AppDomain для загруженных сборок, а вместо этого сканирует файловую систему и загружает библиотеки, которые еще не загружены.
Декомпилировал исходный код EPiServer и обнаружил, что когда для атрибута forceBinFolderScan установлено значение true, среда EPiServer сканирует каждую DLL в папке bin. Он перебирает все библиотеки и загружает их в AppDomain.
Если для этого атрибута установлено значение false, он не сканирует папку bin, а зависит от загрузки сборки ASP.NET.
После того, как сборки загружены в AppDomain из bin (или не загружены, если атрибут имеет значение false), он получает все сборки из AppDomain и затем фильтрует их на основе конфигурации добавления / удаления. Поэтому добавление / удаление тегов не влияет на сканирование папки bin.
На самом деле это поведение и причина такого поведения описаны в документации EPiServer: MEF - Механизм обнаружения (см. Примечание внизу параграфа). Автор просто не упомянул, что это контролируется атрибутом forceBinFolderScan.
ОБНОВИТЬ
Вот пример, который описывает это поведение.
Предположим, что у нас есть две сборки: MyPlugins.dll - которая содержит несколько плагинов и NoPlugins.dll. Также предположим, что эти DLL не загружаются ASP.NET при запуске приложения.
У нас есть эта конфигурация, которая запрещает принудительно сканировать папку bin и включает все сборки, кроме NoPlugins.dll:
<scanAssembly forceBinFolderScan="false">
<add assembly="*" />
<remove assembly="NoPlugins.dll" />
</scanAssembly>
При такой конфигурации MyPlugins.dll и NoPlugins.dll не загружаются в AppDomain и не могут быть сканированы. Таким образом, плагины не будут доступны.
Если мы установим forceBinFolderScan="true":
<scanAssembly forceBinFolderScan="true">
<add assembly="*" />
<remove assembly="NoPlugins.dll" />
</scanAssembly>
При такой конфигурации обе DLL явно загружаются из папки bin в AppDomain. Затем происходит фильтрация и NoPlugins.dll удаляется из коллекции модулей / плагинов. В результате будут загружены плагины из MyPlugins.dll.
ОБНОВЛЕНИЕ 2
Протестировал различные конфигурации, чтобы увидеть, помогают ли оптимизации, но кажется, что фильтрация сборок дает еще худшие результаты.
На моем сайте достаточно много сборок, поэтому для запуска требуется много времени. Я пробовал 3 разных сценария.
1:
<scanAssembly forceBinFolderScan="false">
<add assembly="*" />
<!-- Remove assemblies generated by EPiOptimizer -->
<remove assembly="..." />
</scanAssembly>
2:
<scanAssembly forceBinFolderScan="false">
<add assembly="*" />
</scanAssembly>
3:
<scanAssembly forceBinFolderScan="true">
<add assembly="*" />
</scanAssembly>
Я выполнил простые тесты 3 раза каждый - сделал iisreset и в Chrome обновил страницу и проверил временную шкалу (я знаю, что это не идеальный тест), и вот результаты:
1: 1,3 мин, 1 мин, 1,3 мин
2: 1 мин, 57 с, 1 мин
3: 57 с, 57 с, 57 с
Я пробовал эти тесты еще несколько раз в другом порядке, но результаты были такими же. Поэтому не стоит делать оптимизации, добавляя теги. Кажется, что отфильтровывать сборки, загруженные в AppDomain, дороже, чем сканировать их все. Странно то, что принудительное сканирование папки bin дает лучшие результаты, но, вероятно, это моя проблема с тестированием.
Если для этого флага установлено значение true, EPiServer будет сканировать папку bin во время запуска сайта на наличие сборок, которые имеют плагины EPiServer. Это обнаружение выполняется путем загрузки сборок и проверки, есть ли у них классы с атрибутом плагина EPiServer или они являются модулями инициализации EPiServer.
Вы можете использовать этот инструмент, чтобы проверить, какие сборки можно удалить из этого раздела, чтобы сократить время запуска.
http://www.david-tec.com/2011/11/Optimising-EPiServer-start-up-times-during-build-with-EPiOptimiser/
Если для forceBinFolderScan установлено значение true, механизм инициализации EPiServer будет сканировать все сборки в папке bin. Если сборка содержит ссылку на MEF (System.ComponentModel.Composition.dll), то она сканируется на наличие классов, помеченных атрибутом IInitializableModule. Для всех найденных классов вызывается метод Initialize.
Если для ForceBinFolderScan задано значение false, сборки не сканируются, и вам необходимо явно добавить любые сборки, содержащие плагины, добавив запись в элемент scanAssembly. Например
<scanAssembly forceBinFolderScan="false">
<add assembly="AssemblyWithPlugins.dll" />
</scanAssembly>
Или наоборот, вы можете исключить сборки, в которых, как известно, нет плагинов, или тех, которые вы не хотите сканировать и инициализировать с помощью механизма инициализации:
<scanAssembly forceBinFolderScan="true">
<remove assembly="AssemblyWithOutPlugins.dll" />
</scanAssembly>
Только сканирование определенных сборок может улучшить время запуска сайта, но вы должны помнить об обновлении списка с добавлением любых новых сборок, иначе EPiServer не загрузит плагины в этих сборках.
Вы можете увидеть это действие в журнале Log4Net, установив уровень журнала Warn или выше, вы увидите такие сообщения, как "Not scan {0}, так как в нем нет ссылок на MEF" и т. Д.
Существует отличный пост в блоге об использовании этой функции, чтобы улучшить время запуска сайта