2

我正在为 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-构建后/

作者说将该属性更改为false,但没​​有解释它的含义。将其设置为false会完全停止扫描程序集还是仅在某些条件下扫描它们?

我有相当大的网站,加载需要几分钟。我在 bin 文件夹中有很多程序集,因此只想将扫描限制为包含一些初始化模块或插件的程序集。

4

4 回答 4

4

由于 Asp.Net 构建系统和应用程序启动优化算法,所有程序集可能不会加载到应用程序域中。这可能会在应用程序启动期间执行的 EPiServer 初始化系统中隐藏一些程序集。为避免这种情况 - EPiServer 允许您设置此forceBinFolderScan标志以强制 bin/ 文件夹(以及 v7 的探测文件夹)扫描程序集。如果 flag 设置为 true - EPiServer 不会向 AppDomain 询问已加载的程序集 - 而是扫描文件系统并加载尚未加载的 dll。

于 2013-05-15T08:33:00.473 回答
2

反编译 EPiServer 源码发现当forceBinFolderScan属性设置为true时,EPiServer 框架会扫描 bin 文件夹中的每个 dll。它遍历所有 dll 并将它们加载到 AppDomain 中。

如果此属性设置为false,它不会扫描 bin 文件夹,而是依赖于 ASP.NET 程序集加载。

从 bin 将程序集加载到 AppDomain 后(或者如果属性为false则不加载),它会从 AppDomain 获取所有程序集,然后根据添加/删除配置过滤它们。所以添加/删除标签不会影响 bin 文件夹扫描。

实际上,这种行为和这种行为的原因在 EPiServer 文档中有所描述:MEF - The Discovery Mechanism(参见段落底部的注释)。作者只是没有提到它是由forceBinFolderScan属性控制的。

更新

这是一个描述该行为的示例。

假设我们有两个程序集:MyPlugins.dll - 包含一些插件和NoPlugins.dll。还假设这些 DLL 不是由 ASP.NET 在应用程序启动时加载的。

我们有这个配置,它告诉不要强制扫描 bin 文件夹并包括除NoPlugins.dll之外的所有程序集:

  <scanAssembly forceBinFolderScan="false">
    <add assembly="*" />
    <remove assembly="NoPlugins.dll" />
  </scanAssembly>

使用这样的配置MyPlugins.dllNoPlugins.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 文件夹扫描会得到更好的结果,但可能是我的测试问题。

于 2013-05-15T08:43:18.880 回答
1

将该标志设置为 true,EPiServer 将在站点启动期间扫描 bin 文件夹以查找具有 EPiServer 插件的程序集。此检测是通过加载程序集并检查它们是否具有具有 EPiServer 插件属性的类或 EPiServer 初始化模块来完成的。

您可以使用此工具检查可以从该部分删除哪些程序集,以缩短启动时间。

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

于 2013-05-14T21:14:04.010 回答
0

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 的任何引用”等消息。

有一篇关于利用此功能改善网站启动时间的精彩博客文章

于 2013-05-15T08:43:37.430 回答