我正在攻读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文件夹中有很多程序集,所以想要只扫描那些包含一些初始化模块或插件的程序集。
答案 0 :(得分:4)
由于Asp.Net构建系统和应用启动优化算法,所有程序集可能不会加载到应用程序域中。这可能会隐藏EPiServer初始化系统中的一些程序集,这些程序集在app启动期间执行。为避免这种情况 - EPiServer允许您设置此forceBinFolderScan
标志以强制bin /文件夹(以及v7的探测文件夹)扫描程序集。如果flag设置为true - EPiServer不要求AppDomain加载程序集 - 而是扫描文件系统并加载尚未加载的dll。
答案 1 :(得分: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 。还假设ASP.NET在应用程序启动时未加载这些DLL。
我们有这样的配置,它告诉不要强制扫描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文件夹扫描会产生更好的结果,但可能是我的测试问题。
答案 2 :(得分:1)
将该标志设置为true,EPiServer将在站点启动期间扫描bin文件夹,以查找具有EPiServer插件的程序集。通过加载程序集并检查它们是否具有具有EPiServer插件属性的类或者是EPiServer初始化模块来完成此检测。
您可以使用此工具检查可以从该部分删除哪些程序集,以便改善启动时间。
http://www.david-tec.com/2011/11/Optimising-EPiServer-start-up-times-during-build-with-EPiOptimiser/
答案 3 :(得分:0)
当forceBinFolderScan设置为true时,EPiServer初始化引擎将扫描bin文件夹中的所有程序集。如果程序集包含对MEF(System.ComponentModel.Composition.dll)的引用,则会扫描标记有IInitializableModule属性的类。然后找到的任何类都有其Initialize方法。
如果将forceBinFolderScan设置为false,则不扫描任何程序集,并且必须通过在scanAssembly元素中添加条目来显式添加包含插件的任何程序集。 E.g
<scanAssembly forceBinFolderScan="false">
<add assembly="AssemblyWithPlugins.dll" />
</scanAssembly>
或者相反,您可以排除已知不包含插件的程序集,或者您不希望被扫描的程序集,并初始化初始化引擎:
<scanAssembly forceBinFolderScan="true">
<remove assembly="AssemblyWithOutPlugins.dll" />
</scanAssembly>
仅扫描特定程序集可以缩短站点启动时间,但您必须记住使用添加的任何新程序集更新列表,否则EPiServer将不会加载这些程序集中的任何插件。
您可以在Log4Net日志中看到此活动,通过将日志级别设置为警告或更高,您将看到诸如“不扫描{0}之类的消息,因为它没有对MEF的任何引用”等。
有一篇关于将此功能用于improve site startup time
的博文