避免 aspnet_compiler 运行 PreApplicationStart 方法

24

因此,我的一个网站有一个PreApplicationStartMethod,它应该在应用程序启动之前运行:

[assembly: PreApplicationStartMethod(typeof(ServiceStackAppHost), "Start")]

该方法进行了一些引导操作,并依赖于一些配置的设置。

现在,我想将网站编译为自动化构建流程的一部分 - 因此我调用 aspnet_compiler.exe,但它失败了,因为它运行了 PreApplicationStartMethod:

AfterBuild:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_compiler.exe -v temp -p C:\Projects\ error ASPRUNTIME : The pre-application start initialization method Start on type RedactedNameSpace.ServiceStackAppHost threw an exception with the following error message: Resolution of the dependency failed, type = "..."

如何避免 aspnet_compiler.exe 在编译网站时调用 PreApplicationStartMethod?


绕过此方法的目的是什么?如果在调用aspnet_compiler.exe启动时无法设置在“PreApplicationStart”上设置的配置,那么您如何执行其他操作? - jparthj
aspnet_compiler应该“编译”网站,而不是运行它。我想在将应用程序移动到可以实际运行的环境之前,能够验证是否存在编译时错误。 - driis
你的项目中一定包含 Global.asax 文件,对吧? - jparthj
一篇关于PreApplicationStart的博客文章特别提到它被称为“way early”,在编译开始之前就被调用。不可否认,那篇文章并不是关于precompiling的。你需要使用PreApplicationStart吗?或者将你在那里的代码移动到其他地方是否可以接受? - user743382
2个回答

32

简而言之,您无法防止其运行,并且这是设计上的考虑,但是您可以通过解决问题来解决问题。

为什么PreApplicationStart方法在aspnet_compiler.exe期间运行?

原因是 PreApplicationStartMethod (或基于它构建的 WebActivator )可用于实际影响编译的事情,因此如果省略它,则网站可能无法编译。

举个例子,您可以在 PreAppStart 方法中添加名称空间,然后影响Razor页面的编译。

显然,并不是每个 PreAppStart 方法都需要在使用aspnet_precompiler时运行,但我们会运行所有这些方法,以防需要它们。

检测是否在aspnet_compiler.exe下运行

如果其中的代码在aspnet_compiler下出现故障,则可能需要在 PreAppStart 方法中添加条件逻辑以检测该情况并省略运行代码。

您可以查看 System.Web.Hosting.HostingEnvironment.InClientBuildManager 属性,以确定您的 PreAppStart 方法是否在aspnet_compiler.exe的上下文中运行(在那里将是true ),或在运行时(在那里将是false )。 InClientBuildManager也适用于在VS中构建网站,它使用基本上与aspnet_compiler.exe相同的代码路径。

尝试改为使用PostStart方法

请注意,WebActivator还支持 PostApplicationStartMethod ,并且这些不会在aspnet_compiler下运行。该代码在 Application_Start 之后运行,因此可能或可能不适合您的情况。但是它可能是您的解决方案。

aspnet_compiler.exe调试提示

虽然不是直接相关,但对于调试很有用:您可以通过向 aspnet_compiler.exe 传递 -errorstack 参数来在出现错误时获得更完整的堆栈信息。


هˆڑهˆڑو·»هٹ ن؛†وœ‰ه…³ن½؟用WebActivatorçڑ„PostApplicationStartMethodçڑ„ن؟،وپ¯م€‚ - David Ebbo
2
有没有一种方法可以实际检测出您运行的是编译模式而不是作为实时网站? - Bennor McCarthy
@BennorMcCarthy 我刚刚添加了有关使用 InClientBuildManager 检测它的信息。 - David Ebbo
只是想提醒大家,这种情况可能是因为我在 PreStart 中进行 IoC 初始化时存在松散引用,这些引用是通过反射解析的。由于我使用的 MSBuild/MSDeploy 目标在构建后复制这些引用,所以在尝试发布到 IIS 实例时会出现此错误。在到达这里之前,我必须跟踪一些其他步骤并缩小范围,希望这次 Web Deploy 发布的提及可以收紧谷歌搜索结果;P - TheXenocide

0

PreApplicationStartMethod是一个程序集属性,用于在构建过程的非常早期加载代码。编译器必须加载和运行此代码才能开始编译过程。PreApplicationStartMethod类似于构建过程而不是初始化过程。因此,您可以尝试将代码放入global.asax中的Application_Start方法中!


编译器必须加载和运行此代码,以开始编译过程。这完全是错误的。 - driis
你可以尝试这个解决方案! - jparthj
是的,将代码放在Application_Start中可以工作。问题是它是否可以与PreApplicationStart一起工作。 - driis
同意!那么我的答案是“不行”。这是无法绕过的。如果您遇到错误,可以避免它。但是PreApplicationStartMethod将无论如何运行。 - jparthj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接