问题:如何使代码在本地、QA 和生产中运行时表现不同?
示例:在 ASP.NET MVC 应用程序中,我设置了一个控制器来传递电子邮件通知。在开发机器上本地运行时,我希望将电子邮件发送给开发人员,在QA中我不希望发送任何电子邮件通知,而在生产中我希望将通知发送给他们的预期收件人
谢谢
问题:如何使代码在本地、QA 和生产中运行时表现不同?
示例:在 ASP.NET MVC 应用程序中,我设置了一个控制器来传递电子邮件通知。在开发机器上本地运行时,我希望将电子邮件发送给开发人员,在QA中我不希望发送任何电子邮件通知,而在生产中我希望将通知发送给他们的预期收件人
谢谢
拥有三个不同的 web.configs 并添加一个 AppSetting 告诉您您在哪里,以便您确定是否应该发送电子邮件。
您还可以使用 CompilerOptions 属性在 web.config 中定义常量:
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs"
type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089"
compilerOptions="/d:Test"/>
</compilers>
</system.codedom>
并在您的代码中使用
#if !Test
SendMail();
#endif
这听起来像是您应该使用 IoC 做的事情。我通常使用StructureMap,它允许我设置不同的配置文件。然后我要做的就是配置一个 web.config 开关来设置适当的环境配置文件。
例如,在 StructureMap 中,您可以执行以下操作:
ObjectFactory.Initialize( x => {
x.CreateProfile( "Development", p =>
{
p.Type<IEmailProvider>().Is.OfConcreteType<DeveloperEmailProvider>();
} );
x.CreateProfile( "QA", p =>
{
p.Type<IEmailProvider>().Is.OfConcreteType<NullEmailProvider>();
} );
x.CreateProfile( "Production", p =>
{
p.Type<IEmailProvider>().Is.OfConcreteType<ProductionEmailProvider>();
} );
} );
ObjectFactory.Profile = ConfigurationSettings.AppSettings["Profile"];
对于轻量级项目,我只使用一个 AppSetting 值,然后对于所有电子邮件,通过以下消息传递收件人地址:
公共静态 MailAddress MailTo(字符串电子邮件) { if (Boolean.Parse(ConfigurationManager.AppSettings["RedirectEmails"])) { return new MailAddress(ConfigurationManager.AppSettings["DebugMailbox"]); } 返回新的邮件地址(电子邮件); }
我们较大的项目使用 NAnt 构建脚本,它使用模板配置文件为不同的构建目标生成不同的配置(因此您有一个 Web.Config.template 文件,该文件与 local.properties、test.properties 或发布合并。包含相关变量的属性 XML 文件)。
我会为 System.Net.Mail 如何发送电子邮件的环境配置不同的 web.config。看看 Scott Gu 关于它的博客文章。对于Development,我会让它把电子邮件放在服务器上的某个地方。对于QA,让它不在任何地方发送任何东西,对于Production,让它配置为使用普通的 SMTP 服务器。
我认为 IoC 的答案是一个很好的通用解决方案。对于将电子邮件直接发送到 SMTP 服务器的特定情况,您可以在此处使用配置解决方案:How can I save an email instead of send when using SmtpClient? . 配置解决方案既快速又便宜,尤其是在开发团队对 IoC 不感兴趣的情况下。
我见过一些项目,虽然在另一台机器上有一个中间服务来处理电子邮件。在这种情况下,配置解决方案不起作用。
我在最近的一个项目中这样做了。我的解决方案相当复杂,但简而言之,有两个 Web.config 键可以控制它:EmailTestMode 和 EmailEnabled。如果 EmailTestMode 处于打开状态,则会生成消息,但会发送到特定地址而不是其预期收件人。如果 EmailEnabled 关闭,则记录但不发送消息。
我费力地构建了一个为我管理这些项目的 Messenger 类——我只是调用了一个具有消息的各种属性的方法,它会确定是否发送以及发送到哪里。我还在 Web.config 中有一个单独的配置块,其中包含所有系统消息。这样,发件人、收件人、主题和正文可以很容易地从配置文件中修改。在大多数情况下,正文要么由应用程序生成,要么使用 String.Format() 来填充值。
我使用我的版本控制软件为我做这件事。基本上,我的每个环境(dev、test、qa、prod)都有多个 web.config 文件。现在在版本控制软件中,我将所有文件标记为正确的环境。因此,当我需要构建 qa evnvironment 时,我会得到所有标记为“QA”的文件,依此类推。
我们这样做的方式是在我们的 machine.config 中有两个配置键
ProductionServers="PROD_SERVER"
TestServers="LOCAL_MACHINE|TEST_SERVER"
然后我们有一个函数来测试机器名称(System.Environment.MachineName)与这些值。这样我们就不必更改服务器上的任何配置,当我们想要指向 prod 而不是 test 时,我们只需更改本地 machine.config。