2

问题:如何使代码在本地、QA 和生产中运行时表现不同?

示例:在 ASP.NET MVC 应用程序中,我设置了一个控制器来传递电子邮件通知。在开发机器上本地运行时,我希望将电子邮件发送给开发人员,在QA中我不希望发送任何电子邮件通知,而在生产中我希望将通知发送给他们的预期收件人

谢谢

4

9 回答 9

4

拥有三个不同的 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
于 2010-01-07T18:37:29.430 回答
4

这听起来像是您应该使用 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"];
于 2010-01-07T18:38:27.430 回答
3

对于轻量级项目,我只使用一个 AppSetting 值,然后对于所有电子邮件,通过以下消息传递收件人地址:

公共静态 MailAddress MailTo(字符串电子邮件)
{
    if (Boolean.Parse(ConfigurationManager.AppSettings["RedirectEmails"]))
    {
        return new MailAddress(ConfigurationManager.AppSettings["DebugMailbox"]);
    }

    返回新的邮件地址(电子邮件);
}

我们较大的项目使用 NAnt 构建脚本,它使用模板配置文件为不同的构建目标生成不同的配置(因此您有一个 Web.Config.template 文件,该文件与 local.properties、test.properties 或发布合并。包含相关变量的属性 XML 文件)。

于 2010-01-07T18:46:37.863 回答
1

我会为 System.Net.Mail 如何发送电子邮件的环境配置不同的 web.config。看看 Scott Gu 关于它的博客文章。对于Development,我会让它把电子邮件放在服务器上的某个地方。对于QA,让它不在任何地方发送任何东西,对于Production,让它配置为使用普通的 SMTP 服务器。

于 2010-01-07T18:54:19.773 回答
1

我认为 IoC 的答案是一个很好的通用解决方案。对于将电子邮件直接发送到 SMTP 服务器的特定情况,您可以在此处使用配置解决方案:How can I save an email instead of send when using SmtpClient? . 配置解决方案既快速又便宜,尤其是在开发团队对 IoC 不感兴趣的情况下。

我见过一些项目,虽然在另一台机器上有一个中间服务来处理电子邮件。在这种情况下,配置解决方案不起作用。

于 2010-01-07T18:58:16.190 回答
0

我在最近的一个项目中这样做了。我的解决方案相当复杂,但简而言之,有两个 Web.config 键可以控制它:EmailTestMode 和 EmailEnabled。如果 EmailTestMode 处于打开状态,则会生成消息,但会发送到特定地址而不是其预期收件人。如果 EmailEnabled 关闭,则记录但不发送消息。

我费力地构建了一个为我管理这些项目的 Messenger 类——我只是调用了一个具有消息的各种属性的方法,它会确定是否发送以及发送到哪里。我还在 Web.config 中有一个单独的配置块,其中包含所有系统消息。这样,发件人、收件人、主题和正文可以很容易地从配置文件中修改。在大多数情况下,正文要么由应用程序生成,要么使用 String.Format() 来填充值。

于 2010-01-07T18:37:07.060 回答
0

正如其他人所说,在 web.config 中使用不同的应用程序设置。然后,您的运行时代码可以使用正确版本的设置。

另一种很酷的方法是使用条件属性来构建和调用方法的调试版本。

于 2010-01-07T18:55:40.827 回答
0

我使用我的版本控制软件为我做这件事。基本上,我的每个环境(dev、test、qa、prod)都有多个 web.config 文件。现在在版本控制软件中,我将所有文件标记为正确的环境。因此,当我需要构建 qa evnvironment 时,我会得到所有标记为“QA”的文件,依此类推。

于 2010-01-07T19:33:37.697 回答
0

我们这样做的方式是在我们的 machine.config 中有两个配置键

ProductionServers="PROD_SERVER"
TestServers="LOCAL_MACHINE|TEST_SERVER"

然后我们有一个函数来测试机器名称(System.Environment.MachineName)与这些值。这样我们就不必更改服务器上的任何配置,当我们想要指向 prod 而不是 test 时,我们只需更改本地 machine.config。

于 2010-01-07T19:48:26.243 回答