Asp.net mvc ASP.NET MVC-如何使代码在本地运行时与在QA中运行时与在生产中运行时表现不同

Asp.net mvc ASP.NET MVC-如何使代码在本地运行时与在QA中运行时与在生产中运行时表现不同,asp.net-mvc,configuration,debugging,qa,production,Asp.net Mvc,Configuration,Debugging,Qa,Production,问题: 如何使代码在本地运行、QA运行和生产运行时表现不同 例如: 在ASP.NET MVC应用程序中,我设置了一个控制器来发送电子邮件通知。在开发机器上本地运行时,我希望将电子邮件发送给开发人员;在QA中,我不希望任何电子邮件通知发出;在生产中,我希望通知发送给预期的收件人 谢谢我在最近的一个项目中做了这个。我的解决方案相当复杂,但简而言之,有两个Web.config键可以控制它:EmailTestMode和EmailEnabled。如果EmailTestMode处于启用状态,则会生成邮件,但

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

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


谢谢

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


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

有三个不同的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>

这听起来像是你应该使用IoC做的事情。我通常使用它来设置不同的配置文件。然后我需要做的就是配置一个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"];
ObjectFactory.Initialize(x=>{
x、 CreateProfile(“开发”,p=>
{
p、 Type()是混凝土类型()的;
} );
x、 CreateProfile(“QA”,p=>
{
p、 Type()是混凝土类型()的;
} );
x、 CreateProfile(“生产”,p=>
{
p、 Type()是混凝土类型()的;
} );
} );
ObjectFactory.Profile=ConfigurationSettings.AppSettings[“Profile”];

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

public static MailAddress MailTo(string email) { if (Boolean.Parse(ConfigurationManager.AppSettings["RedirectEmails"])) { return new MailAddress(ConfigurationManager.AppSettings["DebugMailbox"]); } return new MailAddress(email); } 公共静态邮件地址MailTo(字符串电子邮件) { if(Boolean.Parse(ConfigurationManager.AppSettings[“RedirectEmails”])) { 返回新的邮件地址(ConfigurationManager.AppSettings[“DebugMailbox”]); } 返回新的邮件地址(电子邮件); }
我们的大型项目使用NAnt构建脚本,它使用模板配置文件为不同的构建目标生成不同的配置(因此您有一个Web.config.template文件,它与包含相关变量的local.properties、test.properties或release.properties XML文件合并).

我会根据System.Net.Mail发送电子邮件的环境对web.config进行不同的配置。看一看斯科特·顾关于这件事的报道。对于开发,我会让它把电子邮件放到服务器上的某个地方。对于QA,请不要将其发送到任何地方,对于生产请将其配置为使用普通SMTP服务器。

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


另一种很酷的方法是使用构建和调用方法的调试版本。

我认为IoC的答案是一个很好的通用解决方案。对于直接将电子邮件发送到SMTP服务器的特定情况,您可以在此处使用配置解决方案:。配置解决方案既快捷又便宜,特别是如果开发团队在IoC上不是很强大的话


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

我使用版本控制软件来完成这项工作。基本上,我的每个环境都有多个web.config文件(dev、test、qa、prod)。现在,在版本控制软件中,我为所有文件添加了正确环境的标签。因此,当我需要构建qa EVN环境时,我会将所有文件标记为“qa”,以此类推。

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

ProductionServers=“产品服务器”
TestServers=“本地_机器|测试_服务器”


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

似乎是对模式的一种违反直觉的使用。请解释一下为什么您认为这是违反直觉的?IoC旨在让您更容易地加入所需的其他实现服务,所以我认为它完全合适/直观。顺便说一句,这正是我使用IoC的方式-我的web.config有一个设置,告诉我的应用程序加载哪个Ninject模块,然后我有一个用于开发和产品的模块:谢谢James!我认为您和Yuriy都提出了很好的解决方案,但只能将其中一个标记为正确(也许有一天stackoverflow会改变这一点)谢谢你,尤里。我所看到的compilerOptions选项的唯一问题是,它在中等信任环境中无法工作。在我的特定应用程序中,这并不是我的问题,事实证明,这是实现我所需要的最直接的方法。我确实认为詹姆斯下面的解决方案同样有效,我也考虑过这一点。 public static MailAddress MailTo(string email) { if (Boolean.Parse(ConfigurationManager.AppSettings["RedirectEmails"])) { return new MailAddress(ConfigurationManager.AppSettings["DebugMailbox"]); } return new MailAddress(email); }