Reputation: 8261
In an ASP.NET MVC application I have a controller set up to deliver e-mail notifications. When running locally on a development machine I want the e-mails delivered to the developer, when in QA I don't want any e-mail notifications going out and in Production I want the notifications going out to their intended recipients
Upvotes: 2
Views: 704
Reputation: 4358
The way we do it is to have two config keys in our machine.config
ProductionServers="PROD_SERVER"
TestServers="LOCAL_MACHINE|TEST_SERVER"
Then we have a function that tests machine name(System.Environment.MachineName) vs those values. That way we never have to change any configs on the servers and when we want to point at prod instead of test we just change our local machine.config.
Upvotes: 0
Reputation: 286
I use my version control software to do this for me. Basically I have multiple web.config files for each of my environments (dev, test, qa, prod). Now in the version control software I tag all the files for the correct environment. So when I need to build the qa evnvironment I get all the files tagged "QA" and so on.
Upvotes: 0
Reputation: 24480
I think the IoC answer is a good general solution. For the specific case of emails being sent directly to an SMTP server, you could instead use the config solution here: How can I save an email instead of sending when using SmtpClient?. The config solution is quick and cheap, especially if the dev team is not big on IoC.
I've seen projects though where there is an intermediate service on another machine that does the email processing. In this case the config solution does not work.
Upvotes: 1
Reputation: 11858
Like others have said, use different Application Settings in your web.config. Your runtime code can then use the correct version of your settings.
Another cool way of doing this is to use Conditional Attributes to build and call debug versions of your methods.
Upvotes: 0
Reputation: 14281
This sounds like something you should do using an IoC. I typically use StructureMap which would allow me to setup different profiles. Then all I would have to do is have a web.config switch configured to set the appropriate environment profile.
For example, in StructureMap you could do the following:
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"];
Upvotes: 4
Reputation: 7253
I would configure the web.config differently for the environments of how System.Net.Mail sends out the emails. Take a look at Scott Gu's blog post about it. For Development, I'd have it drop the emails on the server somewhere. For QA, have it not send anything anywhere, and for Production have it configured to use the normal SMTP server.
Upvotes: 1
Reputation: 68667
Have three different web.configs and add an AppSetting which tells you where you are so you can determine if you should send an email.
You could also define constants in your web.config using the CompilerOptions attribute:
<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>
And in your code use
#if !Test
SendMail();
#endif
Upvotes: 4
Reputation: 2357
For lightweight projects, I just use an AppSetting value, and then for all emails, pass the recipient address through the following message:
public static MailAddress MailTo(string email) { if (Boolean.Parse(ConfigurationManager.AppSettings["RedirectEmails"])) { return new MailAddress(ConfigurationManager.AppSettings["DebugMailbox"]); } return new MailAddress(email); }
Our larger projects use NAnt build scripts, which use template config files to generate a different configuration for different build targets (so you have a Web.Config.template file, which is merged with either a local.properties, test.properties or release.properties XML file containing the relevant variables).
Upvotes: 3
Reputation: 11759
I did this on a recent project. My solution is fairly involved, but in a nutshell there are two Web.config keys that control this: EmailTestMode and EmailEnabled. If EmailTestMode is on, messages are generated but sent to a specific address rather than their intended recipient. If EmailEnabled is off, messages are logged but not sent.
I went to the trouble of building a Messenger class that manages these items for me - I just call a method with the various attributes of the message, and it figures out whether and where to send it. I also have a separate configuration block in Web.config that contains all of the system messages. That way, the sender, recipient, subject and body can be easily modified from a configuration file. In most cases the body is either generated by the app or uses String.Format() to fill in values.
Upvotes: 0