C# MVC中的UI与业务逻辑

C# MVC中的UI与业务逻辑,c#,asp.net-mvc,C#,Asp.net Mvc,所以MVC被分为 模型 看法 控制器层 我以为在准备了很多页面后,我已经掌握了每一层的功能,但有一个方面我仍然感到困惑,那就是模型或控制器中是否应该有东西 我知道数据存储类应该放在控制器中 我知道UI修改器(即拉取正确的模型)应该放在控制器中 但是模型修改器呢。例如,如果我们采用软件购物车的方法,比如说有人点击了结账按钮,填写了他们的付款详细信息,并获得了全部批准,那么回发正好可以解决这个问题 回发对象需要 在数据库表中添加一个条目,表示允许X用户下载Y软件 向用户发送收据 记录购买情况 通

所以MVC被分为

  • 模型
  • 看法
  • 控制器层
我以为在准备了很多页面后,我已经掌握了每一层的功能,但有一个方面我仍然感到困惑,那就是模型或控制器中是否应该有东西

我知道数据存储类应该放在控制器中 我知道UI修改器(即拉取正确的模型)应该放在控制器中

但是模型修改器呢。例如,如果我们采用软件购物车的方法,比如说有人点击了结账按钮,填写了他们的付款详细信息,并获得了全部批准,那么回发正好可以解决这个问题

回发对象需要

  • 在数据库表中添加一个条目,表示允许X用户下载Y软件
  • 向用户发送收据
  • 记录购买情况
  • 通常(在非MVC的情况下)我会创建一个类来处理软件表的访问生成,它将调用EF来存储信息。我将有一个第二类发送通知,第三类记录信息


    我应该在MVC中仍然拥有这些类吗?如果是的话,它们是作为控制器的类还是作为模型的类

    上面定义的所有三个点构成应用程序模型的一部分;控制器应该只处理模型和呈现给用户的UI表示(视图)之间的编排

    坚持坚实的原则,我们绝对同意(至少)处理三个独立的组成部分:

  • 保存有关用户x下载软件y的数据
  • 签发收据
  • 伐木
  • 您可以通过多种方式组织体系结构和组件来实现这一点。一种方法是使用特定于应用程序的组件/服务,该组件/服务依赖于这三个组件,并使用它们执行列出的操作。然后控制器只对这个组件有依赖性。

    以更详细的方式详述,考虑如下:

    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();
        }
    }
    
    公共类签出控制器
    {
    私有只读ICommandHandler _checkoutHandler;
    公共签出控制器(ICommandHandler签出处理程序)
    {
    _checkoutHandler=checkoutHandler;
    }
    [HttpPost]
    公共虚拟操作结果发布(CheckoutViewModel viewModel)
    {
    如果(!ModelState.IsValid)返回视图(viewModel);
    var命令=Mapper.Map(viewModel);
    _Handle(命令);
    返回重定向到操作(“完成”);
    }
    公共虚拟操作结果完成()
    {
    返回视图();
    }
    }
    
    控制员一点也不做生意。它为用户提供控制流。现在,考虑将这个依赖项注入控制器:

    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
        }
    }
    
    公共类DomainCheckoutCommandHandler:ICommandHandler
    {
    私有只读IEntityDataStorage _repos;
    私人只读IEmailSender\u电子邮件;
    私有只读ILogger_日志;
    公共域CheckOutCommandHandler(IEntityDataStorage repos,
    IEmailSender电子邮件,ILogger日志)
    {
    _回购=回购;
    _电子邮件=电子邮件;
    _log=log;
    }
    公共无效句柄(CheckoutCommand命令)
    {
    //使用_repos将条目添加到数据库表中
    //使用电子邮件发送收据
    //使用_log记录购买
    }
    }
    
    在中有一些关于使用interfaces+DI的好信息


    最好的部分是您可以将所有其他代码——接口、域类和其他接口实现——全部移出MVC项目。这样,MVC项目中的任何内容都不会有任何商业价值。它只是委托给由您的业务层或其他类库实现的接口。

    这是所有与模型相关的内容,因此它肯定是模型层。但这并不意味着它应该是cart类的一部分。你可能有一个CartWriter或CartReader来处理DB(或其他地方)中的cart存储。@RussCam,我从你的书中复制并粘贴了它。