Декомпилировал исходный код 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