Для обработки этих видов сценариев вы должны использовать Dependency Injection (лично я использовал его в 99,9% проектах, потому что это единственный способ, которым Вы можете протестировать устройство его). Библиотека Injection Dependency (Autofac, Ninject, Castle Windsor, Simple Injector и другие) позволяет вам разрешать зависимости в базе времени выполнения при некоторой конфигурации. Например, вы у вас есть услуги связи, который отвечает отправлять сообщения электронной почты:
public interface ICommuniucationService
{
void SendEmail(....);
}
public class CommunicationService : ICommuniucationService
{
public void SendEmail(...)
{
//real implementation of sending email
}
}
public class FakeCommunicationService : ICommuniucationService
{
public void SendEmail(...)
{
//do nothing.
return;
}
}
Мой контроллер будет иметь частную собственность типа ICommuniucationService, который собирается быть реализован с помощью библиотеки инъекции зависимостей с помощью инъекции конструктора:
public class MyController : Controller{
//this will be resolved in runtime(either CommuniucationService or FakeCommunicationService)
private readonly ICommuniucationService EmailSvc;
// Use constructor injection for the dependencies
public MyController(ICommuniucationService svc) {
this.EmailSvc= svc;
}
public ActionResult Create(string name){
// create and save to database
// if success
// select admin emails from database.
// create email content and subject.
this.EmailSvc.SendEmail(...)
//The action code doesn't change neither for
}
}
При настройке инъекции зависимостей контейнера вы могли бы сделать что-то вроде этого (Simple injector example похожее на это):
protected void Application_Start(object sender, EventArgs e) {
var container = new Container();
#if DEBUG
container.Register<ICommuniucationService, FakeCommuniucationService>(Lifestyle.Singleton);
#else
container.Register<ICommuniucationService, CommuniucationService>(Lifestyle.Singleton);
#endif
container.Verify();
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
}
Итак, при такой конфигурации, когда ваш проект работает с режимом DEBUG, вы регистрируете FakeCommuniucationService
, который не отправляет электронные письма, а когда вы запускаете в режиме RELEASE (который вы должны использовать при публикации приложения), то зарегистрирован реальный CommuniucationService