Что означает атрибут forceBinFolderScan в файле EPiServerFramework.config?

Я готовился к экзамену EPiServer и прочитал эту статью об инициализации EPiServer: http://world.episerver.com/Documentation/Items/Tech-Notes/EPiServer-CMS-6/EPiServer-CMS-60/Инициализация/

В нем описывается, как настроить инициализацию, чтобы ограничить сборки, которые будут сканироваться во время запуска, но упоминается атрибут forceBinFolderScan, который не описан. Например, для него всегда установлено значение true.

Я также нашел другую статью, в которой описывается, как улучшить время запуска сайта EPiServer: http://world.episerver.com/Blogs/Alexander-Haneng/Dates/2011/12/Starting-CMS-6-R2.-sites-faster-after-build/

Автор предлагает изменить этот атрибут на false, но не объясняет, что это значит. Установка false останавливает ли сканирование сборок вообще или сканирует их только при определенных условиях?

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


person marisks    schedule 14.05.2013    source источник


Ответы (4)


Из-за системы сборки Asp.Net и алгоритмов оптимизации запуска приложения все сборки не могут загружаться в домен приложения. Это может скрыть некоторые сборки от системы инициализации EPiServer, которая выполняется во время запуска приложения. Чтобы избежать этого, EPiServer позволяет вам установить этот флаг forceBinFolderScan, чтобы принудительно сканировать папку bin/ (и папку проверки для v7) на наличие сборок. Если для флага установлено значение true, EPiServer не запрашивает у AppDomain загруженные сборки, а вместо этого сканирует файловую систему и загружает еще не загруженные DLL.

person wałdis iljuczonok    schedule 15.05.2013
comment
Валдис прав - флаг forceBinFolderScan просто принудительно сканирует корзину и загружает сборки в AppDomain. Для получения дополнительной информации см. мой ответ. - person marisks; 17.05.2013

Декомпилировал исходный код EPiServer и обнаружил, что когда для атрибута forceBinFolderScan установлено значение true, платформа EPiServer сканирует каждую DLL в папке bin. Он перебирает все DLL и загружает их в AppDomain.

Если для этого атрибута задано значение false, он не сканирует папку bin, а полагается на загрузку сборки ASP.NET.

После того, как сборки загружены в AppDomain из корзины (или не загружены, если атрибут 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 дает лучшие результаты, но, вероятно, это моя тестовая проблема.

person marisks    schedule 15.05.2013

Если для этого флага установлено значение true, EPiServer будет сканировать папку bin во время запуска сайта на наличие сборок с подключаемыми модулями EPiServer. Это обнаружение выполняется путем загрузки сборок и проверки наличия у них классов с атрибутом подключаемого модуля EPiServer или модулей инициализации EPiServer.

Вы можете использовать этот инструмент, чтобы проверить, какие сборки можно удалить из этого раздела, чтобы сократить время запуска.

http://www.david-tec.com/2011/11/Optimising-EPiServer-start-up-times-during-build-with-EPiOptimiser/

person nimeshjm    schedule 14.05.2013
comment
Но когда для этого флага установлено значение false, папка bin не сканируется? Если да, то как загружаются плагины и модули инициализации? Теперь в моем проекте установлено значение false и есть такой тег добавления: ‹add Assembly=* /› Кажется, что инициализация проходит успешно, и плагины тоже найдены. - person marisks; 15.05.2013
comment
Плагины и модули будут найдены в любом случае. Вопрос в том, сколько будет обнаружено, если для параметра forceBinFolderScan установлено значение false. Этот флаг был введен из-за системы сборки Asp.Net - во время запуска приложения (когда работает система инициализации EPiServer) все сборки не могут загружаться в домен приложения (оптимизация). - person wałdis iljuczonok; 15.05.2013
comment
Вы сказали ему не сканировать корзину, установив для него значение false, но затем вы говорите ему сканировать все сборки, используя подстановочный знак ‹add Assembly=* /› - person tompipe; 15.05.2013
comment
Правильно, вы говорите ему не сканировать папку bin и добавлять из нее все сборки, за исключением тех, у которых есть ключевое слово ‹remove›. - person nimeshjm; 15.05.2013
comment
Это неправда. Когда для параметра установлено значение false, вы говорите ему не сканировать сборки явно, но они все еще загружаются ASP.NET в какое-то время. ‹add Assembly=/› и ‹remove› просто фильтрует загруженные сборки в AppDomain. Это означает, что если ваша сборка не загружена в AppDomain, она не будет сканироваться на наличие каких-либо модулей инициализации или плагинов, даже если у нее есть ‹add Assembly= /›. - person marisks; 17.05.2013

Если для параметра 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, установив уровень журнала «Предупреждение» или выше, вы увидите такие сообщения, как «Не сканировать {0}, так как в нем отсутствуют какие-либо ссылки на MEF» и т. д.

В блоге есть отличная запись об использовании этой функции для улучшить время запуска сайта

person tompipe    schedule 15.05.2013
comment
Явное указание, какие сборки сканировать путем добавления/удаления, ни на что не влияет, если они не загружены в AppDomain. add/remove предназначен только для фильтрации сборок, загруженных в AppDomain. Также тег удаления используется только при наличии тега ‹add Assembly=* /› - в противном случае он игнорируется. - person marisks; 15.05.2013