让我为您提供另一种方法,让您知道您是在 Azure、Azure Emulator、IIS 还是在本地运行集成测试。这一点很重要,因为在 IIS 中调试表示最终将在 Azure 中运行的纯 Web 项目或运行甚至可能在 IIS 之外运行的集成测试是有用且更快的。这意味着您可以更快地调试项目,而不是每次都浪费时间加载/运行天蓝色计算模拟器。
有几种方法可以检查这个和那个,但这里有另一种方法可以帮助您在所有情况下移动以获得良好的 ALM 和开发。
您有四种可用的机制可供使用:
- IIS 中的 HostingEnvironment 对象
- Azure 或 Azure 模拟器中的 RoleEnvironment 对象
- System.Environment 对象随处可见。
- 配置 - 在我的例子中是 web.config、web.debug.config、web.release.config、web.debug.staging.config、web.release.production.config、app.config、ServiceConfiguration.Local.cscfg、 ServiceConfiguration.CloudStaging.cscfg 和 ServiceConfiguration.CloudProduction.cscfg
问题在于:如果您尝试在 IIS 中访问 RoleEnvironment.IsAvailable 或 RoleEnvironment.IsEmulated 而不在 Emulator 或 Azure 中运行 - 您将收到异常。如果环境尚未准备好,在带有 IIS 的 Azure 模拟器中也会出现异常 - 模拟器和 IIS 一起运行并且 IIS 不会等待模拟器,即使您在到达 Global.asax.cs 之前通过了 RoleEntryPoint。这个“东西”消除了像那样等待的可能性
while(!RoleEnvironment.IsAvailable)
并快速干净地解决问题。此问题还消除了 RoleEnvironment.IsEmulated 的使用,因为它会在本地 IIS 或本地集成测试中引发异常,并且无法在它之前检查 RoleEnvironment.IsAvailable,因为如果您等待它在 Azure 或 Azure Emulator 之外准备好你会等待即将出现的东西。
旁注:有时在模拟器环境中可以稍后加载,然后您的 MVC 项目和访问 RoleEnvironment 属性会引发异常。这可以通过调用
来轻松缓解
while(!RoleEnvironment.IsAvailable)
旁注结束。
附注 2
像这样在 RoleEntryPoint 中设置环境变量:
public class WebRole : RoleEntryPoint
{
public override bool OnStart()
{
Environment.SetEnvironmentVariable("CodeRunsInAzure","true");
}
}
不会工作,因为they run in different places 并且您无法像那样检索它:
Environment.GetEnvironmentVariable("CodeRunsInAzure")
在 Global.asax.cs 或您的 Web/Worker 项目的其他地方。否则问题很容易解决。
旁注 2 结束。
解决方案分为两部分。第一个在您的配置文件中。只需在需要它的所有配置中设置变量 - *.cscfgs :
<Setting name="RunsInAzureCloudEnv" value="true/false"/>
在 ServiceConfiguration.Local.cscfg - false 和 cscfg 中的其他任何地方 - true。然后在 web.*.config / app.config 中相应地
<add key="RunsInAzureCloudEnv" value="true/false"/>
这样变量只会在您发布或在模拟器中运行时设置为 true,否则将为 false。
使用此功能的一种情况是您只想在 azure 中运行代码 - 例如在您的 IDatabaseInitializer 自定义实现中将旧数据库的版本从已停用的 WEB 版本更新为 BASIC。在这种情况下,您只需要在 Azure 中运行您的代码,并且仅当它不在模拟器中而是在您的暂存或生产环境中运行。示例用法如下:
// check the variable that is set only in azure environment
var runsInAzureEnvStr = CloudConfigurationManager.GetSetting("RunsInAzureCloudEnv");
bool runsInAzureEnv = false;
Boolean.TryParse(runsInAzureEnvStr, out runsInAzureEnv);
if(!runsInAzureEnv)
{
return;
}
如果只有模拟器在 MVC 启动之前准备好:
if(RoleEnvironment.IsAvailable && !RoleEnvironment.IsEmulated)
就够了。
如果有人知道如何让这两者以准确的顺序发生并分享——那就太好了。