ASP.NET MVC - Как заставить код вести себя по-разному при выполнении локально, в QA и в производственной среде

Вопрос: Как заставить код вести себя по-разному при выполнении локально, в QA и в продакшене?

Пример: в приложении ASP.NET MVC у меня есть контроллер, настроенный для доставки уведомлений по электронной почте. При запуске локально на машине для разработки я хочу, чтобы электронные письма доставлялись разработчику, а в QA я не хочу, чтобы какие-либо уведомления по электронной почте выходили и находились в < strong> Production Я хочу, чтобы уведомления доходили до их предполагаемых получателей

Спасибо


person wgpubs    schedule 07.01.2010    source источник


Ответы (9)


Создайте три разных файла web.configs и добавьте AppSetting, который сообщает вам, где вы находитесь, чтобы вы могли определить, следует ли вам отправлять электронное письмо.

Вы также можете определить константы в своем web.config с помощью атрибута CompilerOptions:

<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
person Yuriy Faktorovich    schedule 07.01.2010
comment
Мне нравится идея опций компилятора. :) - person GalacticCowboy; 07.01.2010
comment
Спасибо, Юри. Единственная проблема, которую я вижу с параметром compilerOptions, заключается в том, что он не работает в средах со средним уровнем доверия. Это не проблема для меня в моем конкретном приложении, и это оказался наиболее простой способ сделать то, что мне нужно. Я действительно думаю, что приведенное ниже решение Джеймса также верно, и я тоже это учел. - person wgpubs; 12.01.2010

Это похоже на то, что вам следует делать с помощью 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"];
person jamesaharvey    schedule 07.01.2010
comment
Похоже на нелогичное использование шаблонов. - person Yuriy Faktorovich; 07.01.2010
comment
Не хотите ли объяснить, почему вы считаете это нелогичным? - person jamesaharvey; 07.01.2010
comment
IoC предназначен для упрощения использования альтернативных реализаций требуемых сервисов, поэтому я считаю его полностью подходящим / интуитивно понятным. - person Frank Schwieterman; 07.01.2010
comment
Кстати, именно так я использую IoC - в моем web.config есть параметр, который сообщает моему приложению, какой NinjectModule загружать, а затем у меня есть модуль для Dev и Prod: stum.de/2009/12/30/ < / а> - person Michael Stum; 07.01.2010
comment
Спасибо, Джеймс! Я думаю, что и вы, и Юрий представляете хорошие решения, но смогли отметить только одно как правильное (возможно, stackoverflow изменит это однажды). - person wgpubs; 12.01.2010

Для легких проектов я просто использую значение AppSetting, а затем для всех писем передаю адрес получателя в следующем сообщении:

public static MailAddress MailTo(string email)
{
    if (Boolean.Parse(ConfigurationManager.AppSettings["RedirectEmails"]))
    {
        return new MailAddress(ConfigurationManager.AppSettings["DebugMailbox"]);
    }

    return new MailAddress(email);
}

В наших более крупных проектах используются сценарии сборки NAnt, которые используют файлы конфигурации шаблонов для создания другой конфигурации для разных целей сборки (так что у вас есть файл Web.Config.template, который объединен либо с local.properties, test.properties, либо с выпуском. properties XML-файл, содержащий соответствующие переменные).

person Keith Williams    schedule 07.01.2010

Я бы настроил web.config по-разному для среды, в которой System.Net.Mail рассылает электронные письма. Взгляните на запись в блоге Скотта Гу об этом . Для разработки я бы попросил оставить электронные письма где-нибудь на сервере. Для QA, пусть он ничего никуда не отправляет, а для Производства настройте его на использование обычного SMTP-сервера.

person Agent_9191    schedule 07.01.2010

Я думаю, что ответ IoC - хорошее общее решение. В конкретном случае, когда электронные письма отправляются непосредственно на SMTP-сервер, вы можете вместо этого использовать решение для конфигурации здесь: Как я могу сохранить электронное письмо вместо отправки при использовании SmtpClient?. Конфигурационное решение быстрое и дешевое, особенно если команда разработчиков не очень разбирается в IoC.

Я видел проекты, в которых на другом компьютере есть промежуточная служба, которая обрабатывает электронную почту. В этом случае конфигурационное решение не работает.

person Frank Schwieterman    schedule 07.01.2010

Я сделал это в недавнем проекте. Мое решение довольно сложное, но вкратце есть два ключа Web.config, которые этим управляют: EmailTestMode и EmailEnabled. Если EmailTestMode включен, сообщения создаются, но отправляются на определенный адрес, а не на предполагаемого получателя. Если EmailEnabled выключен, сообщения регистрируются, но не отправляются.

Я столкнулся с проблемой создания класса Messenger, который управляет этими элементами за меня - я просто вызываю метод с различными атрибутами сообщения, и он определяет, нужно ли его отправлять и куда. У меня также есть отдельный блок конфигурации в Web.config, который содержит все системные сообщения. Таким образом, отправитель, получатель, тема и текст могут быть легко изменены из файла конфигурации. В большинстве случаев тело либо создается приложением, либо использует String.Format () для заполнения значений.

person GalacticCowboy    schedule 07.01.2010

Как уже говорили другие, используйте разные настройки приложения в своем web.config . Тогда ваш рабочий код может использовать правильную версию ваших настроек.

Еще один отличный способ сделать это - использовать условные атрибуты для создания и вызова отладочных версий ваших методов.

person kervin    schedule 07.01.2010

Я использую свое программное обеспечение для контроля версий, чтобы сделать это за себя. В основном у меня есть несколько файлов web.config для каждой из моих сред (dev, test, qa, prod). Теперь в программе контроля версий я помечаю все файлы для правильной среды. Поэтому, когда мне нужно создать qa evnvironment, я получаю все файлы с меткой «QA» и так далее.

person Joe    schedule 07.01.2010

Мы делаем это так, чтобы в файле machine.config было два ключа конфигурации.

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

Затем у нас есть функция, которая проверяет имя машины (System.Environment.MachineName) на соответствие этим значениям. Таким образом, нам никогда не придется менять какие-либо конфигурации на серверах, и когда мы хотим указать на prod вместо test, мы просто меняем наш локальный файл machine.config.

person Jeff Keslinke    schedule 07.01.2010