【问题标题】:How should I encapsulate my MVC-Action in order to avoid code duplication?我应该如何封装我的 MVC-Action 以避免代码重复?
【发布时间】:2015-10-16 08:00:14
【问题描述】:

我有两个类——在这个特殊情况下是 MVC-Controlles——它们有一个通用的控制器动作(一个从 JavaScript 调用的 JSON 动作)。由于代码重复,我想将此操作放在父控制器类中。我们已经有一个控制器基类,它继承自 Controller 并用作基类,具有通用功能,来自其他 6 个控制器。我的 JSON 动作实际上只对 2 个控制器通用,所以我认为将我的 JSON 动作放在其他 6 个控制器已经使用的基本控制器中并不是一个好主意。这是现有的类层次结构图:

Existing Controller class hierarchy

我应该把我的 JSON 动作放在哪里以避免代码重复?我的想法是继承类 ControllerBase - 比如说 ControllerBaseExtended - 并将我的 JSON 动作放在这里。所以现在,我的 2 个控制器可以继承自 ControllerBaseExtended 而不是 ControllerBase。这就是类层次结构最终的样子:

Final Controller class hierarchy

有没有更好的方法来解决这个问题?

【问题讨论】:

    标签: c# asp.net-mvc inheritance encapsulation code-duplication


    【解决方案1】:

    不要创建另一个基本控制器,而是将两个动作中的代码提取到另一个类中,例如JsonAction 处理器。然后你需要调用那个实现。

    public class JsonActionHelper
    {
        public JsonResult Something()
        {
            //do something common
            return new JsonResult();
        }
    }
    

    然后你可以从你的行动中调用它

    public JsonResult Action1()
    {
        return new JsonActionHelper().Something();
    }
    
    public JsonResult Action2()
    {
        return new JsonActionHelper().Something();
    }
    

    如果你有 UnitTests,那么你应该从 JsonActionHelper 中提取接口并将其注入到你的控制器中。

    但是,如果您有 2 个相同的操作,为什么不使用一个操作并通过 JavaScript 从不同的视图调用它?

    【讨论】:

    • 我想我会尝试使用这种组合解决方案而不是继承。两个控件的操作相同,但操作的结果来自服务对象。此服务对象是特定于控制器的。所以我认为问题现在转移到了服务/存储库层。
    【解决方案2】:

    将所有控制器更改为继承 BaseController 而不是 Controller。

    听起来你已经在这样做了....但由于某种原因它并不好,您能否更好地解释一下为什么这不适合您... p>

    public class [my]Controller : BaseController
    {
        public ResualtAction [my]Action 
            return Base.Something();
        }
    }
    
    public class BaseController : Controller
    {
        public CustomeReturnAction Something()
        {
            return new CustomeReturnAction();
        }
    }
    

    或者你只是想更好地组织它....

    如果是这种情况,那么只需将所有返回操作类型移动到另一个类中,并让您的 BaseController 从中继承,我认为您已经说过了,如果您是,那很好。

    【讨论】:

    • 我只是想更好地组织我的源代码并了解其他人如何解决这个问题。我不知何故不想继承自定义基本控制器,但我不知道如何以另一种方式解决问题。
    【解决方案3】:

    这取决于重复代码的功能。您可以使用继承或组合(使用注入的类)中的任何内容来重用不同控制器中的代码。

    例如:我们有一个用于计算产品价格的 Calculation 类,并使用依赖注入将此逻辑注入到不同的控制器中。然后控制器使用这个计算器来呈现输出。

    也许研究一下 ASP.Net MVC 的依赖注入。我推荐Simple Injector。它很好地集成到了 ASP.Net MVC 框架中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多