There are situations where the deployed environment (development, test, or production, for example) might dictate the outcome of certain actions.
For example, perhaps a successful "user registration" process will send a notification email to the new user. Environment-specific actions:
- Development: Do not actually send the email. Email logs will provide enough for developers.
- Test: Send all emails to some [email protected] inbox and not to the user's address.
- Production: Send the email to the user.
I have listed three possible solutions below.
CurrentEnvironment configuration value
One way of solving this, which I have seen a lot, is to have some configuration value (whether it be in some xml config file or in the database) such as CurrentEnvironment
which specifies the current environment in which the system is deployed to. This would require case/if checks in code to determine the desired action:
if(CurrentEnvironment == Environment.Test)
{
// Send all emails to some [email protected] inbox.
}
else if(CurrentEnvironment == Environment.Production)
{
// Send the email to the user.
}
This is not a maintainable solution in my opinion.
Wipe all email addresses
Another method is to run a change script, once restoring a database, to do the following:
- Remove all user email addresses (in development),
- Replace all user email addresses with [email protected] (in test)
This is an extra step in the release process which, if missed, could have some dangerous results. Additionally, this solution only fixes the email problem. There are perhaps many other situations where the environment matters.
Config transformation
Another idea is to use web.config transformations. This way the config can be different for different environments. For example, we will have the following configs:
web.config
web.Development.config
web.Test.config
web.Production.config
The transformation can then use different "providers" or set certain attributes according to the environment. For example, an overrideDeliveryAddress
can be set in the web.Test.config
:
<EmailService>
<providers>
<add
name="EmailServiceProvider"
type="CustomProviders.EmailServiceProvider, CustomProviders"
smtp="smtp.domain.com" password="xyz"
overrideDeliveryAddress="[email protected]"
enabled="true"
/>
</providers>
</EmailService>
This solution requires much more work, but is more maintainable and less invasive. Code is now environment-ignorantoblivious.
What other ways can the above be achieved? Should code EVER be environment aware? Suggestions and critique please. What other ways can the above be achieved? Should code EVER be environment aware?