要更详细地扩展Russ 的出色答案,请考虑以下几点:
public class CheckoutController
{
private readonly ICommandHandler<CheckoutCommand> _checkoutHandler;
public CheckoutController(ICommandHandler<CheckoutCommand> checkoutHandler)
{
_checkoutHandler = checkoutHandler;
}
[HttpPost]
public virtual ActionResult Post(CheckoutViewModel viewModel)
{
if (!ModelState.IsValid) return View(viewModel);
var command = Mapper.Map<CheckoutCommand>(viewModel);
_checkoutHandler.Handle(command);
return RedirectToAction("Complete");
}
public virtual ActionResult Complete()
{
return View();
}
}
控制器根本没有做任何生意。它为用户提供控制流。现在,考虑将这个依赖注入到控制器中:
public class DomainCheckoutCommandHandler : ICommandHandler<CheckoutCommand>
{
private readonly IEntityDataStorage _repos;
private readonly IEmailSender _email;
private readonly ILogger _log;
public DomainCheckoutCommandHandler(IEntityDataStorage repos,
IEmailSender email, ILogger log)
{
_repos = repos;
_email = email;
_log = log;
}
public void Handle(CheckoutCommand command)
{
// use _repos to Add an entry to a database table
// use _email to issue the receipt
// use _log to log the purchase
}
}
在这 三篇 文章中有一些关于像这样使用接口 + DI 的重要信息。
最好的部分是您可以将所有其他代码——接口、域类和其他接口实现——完全移到 MVC 项目之外。这样,MVC 项目中的任何事情都不会做任何业务。它只是委托给由您的业务层或其他类库实现的接口。