Asp.net mvc 将控制器逻辑提取到扩展存储库功能的服务中是一个好主意吗

Asp.net mvc 将控制器逻辑提取到扩展存储库功能的服务中是一个好主意吗,asp.net-mvc,design-patterns,service,extraction,Asp.net Mvc,Design Patterns,Service,Extraction,我有一个名为List的控制器POST操作,它接受一个状态变量,该变量可以是以下值{“all”、“active”、“inactive}。然后我根据控制器内部的“status”值进行了存储库调用。控制器如下所示: [HttpPost] public ActionResult List(string status) { return View(GetJobTitlesByStatus(status)); } private IList<J

我有一个名为List的控制器POST操作,它接受一个状态变量,该变量可以是以下值{“all”、“active”、“inactive}。然后我根据控制器内部的“status”值进行了存储库调用。控制器如下所示:

    [HttpPost]
    public ActionResult List(string status)
    {
        return View(GetJobTitlesByStatus(status));
    }

    private IList<JobTitle> GetJobTitlesByStatus(string status)
    {
        IList<JobTitle> jobTitles;

        switch (status)
        {
            case "All":
                jobTitles = jobTitleRepository.GetAll();
                break;
            case "Active":
                jobTitles = jobTitleRepository.GetActive();
                break;
            case "Inactive":
                jobTitles = jobTitleRepository.GetInactive();
                break;
            default:
                jobTitles = new List<JobTitle>();
                break;
        }
    }
[HttpPost]
公共操作结果列表(字符串状态)
{
返回视图(GetJobTitlesByStatus(状态));
}
私有IList GetJobTitlesByStatus(字符串状态)
{
职业头衔;
开关(状态)
{
案例“全部”:
jobTitles=jobTitleRepository.GetAll();
打破
“活动”案例:
jobTitles=jobTitleRepository.GetActive();
打破
“非活动”情况:
jobTitles=jobTitleRepository.GetInactive();
打破
违约:
jobTitles=新列表();
打破
}
}
我认为switch语句中的代码太多,无法放在控制器中,因此我将其提取到服务中,然后该服务进行相应的存储库调用。例如:

public class JobTitleService : JobTitleRepository, IJobTitleService, IJobTitleRepository
{
    public JobTitleService(ISession session) : base(session) { }
    public IList<JobTitle> GetJobTitlesByStatus(string status)
    {
        IList<JobTitle> jobTitles;

        switch (status)
        {
            case "All":
                jobTitles = base.GetAll();
                break;
            case "Active":
                jobTitles = base.GetActive();
                break;
            case "Inactive":
                jobTitles = base.GetInactive();
                break;
            default:
                jobTitles = new List<JobTitle>();
                break;
        }

        return jobTitles;
    }
}
公共类JobTitleService:JobTitleRepository、IJobTitleService、IJobTitleRepository
{
公共事业标题服务(ISession session):基本(session){}
公共IList GetJobTitlesByStatus(字符串状态)
{
职业头衔;
开关(状态)
{
案例“全部”:
jobTitles=base.GetAll();
打破
“活动”案例:
jobTitles=base.GetActive();
打破
“非活动”情况:
jobTitles=base.GetInactive();
打破
违约:
jobTitles=新列表();
打破
}
返回职务名称;
}
}
我个人认为这非常有效,特别是因为我使用依赖注入将服务引入控制器。我有以下问题:

1) 您认为从控制器中提取开关语句逻辑是一个好主意吗?
2) 您认为让JobTitleService继承JobTitleRepository比 是否将iJobstitleRepository传递到服务的构造函数中(使用依赖项注入)?
3) JobTitleService使用的设计模式是否有一个特殊名称?

1)是的,业务逻辑不应该在控制器中。控制器实际上只是将表示连接到逻辑。理想情况下,逻辑是以一种更面向对象的方法来执行的,而不是以更程序化的方法来执行的,但不要劝阻只要代码简单且可支持,过程性并不是一件坏事。这种设计可以让您在需要时将服务类移动到实际的独立服务中

2) 我在量化它时遇到了困难,但我会犹豫是否让服务从存储库继承。在这个特定的设计中,我将服务视为存储业务逻辑过程的地方,存储库将作为持久性感知组件注入(理想情况下,业务逻辑不应该是持久性感知的).我只是觉得随着系统的发展,它能更清晰地将关注点分开,更容易对设计进行全面的摸索。但这可能只是我个人的观点

3) 我相信在简历上一定有一个正式的名字:)“面向服务的体系结构”“和其他流行语一起出现在我的脑海里。我对术语从来都不在行,所以在这方面我帮不了什么忙。但是有很多关于这个主题的阅读材料。这看起来是一本很好的读物:也可以在这里查找参考资料:

  • 是-控制器应负责选择结果、准备模型,然后将模型传递给视图进行渲染。其他一切都应该委托给其他地方,通常是服务。直接取自:

    控制器接收输入和输出 通过拨打电话发起响应 在模型对象上。控制器接受 来自用户的输入,并指示 要执行操作的模型和视口 基于这一输入

  • 不,您的服务不应从存储库继承。该服务需要与存储库协作以完成其功能,因此它是“has-a”关系,而不是“is-a”关系。现在,这可能并不明显,因为您的服务只是到存储库的一个通道,但一旦您的服务开始执行服务应该执行的操作(协调来自一个或多个协作者的操作),它就会立即变得明显,因为您将只能从这些协作者中的一个继承

    事实上,在这种情况下,如果您的服务只是一个围绕存储库的直接包装器,那么它不会添加任何内容,只是一个间接层——如果它保持如此简单,我将放弃它,直接查询存储库。通常情况下,事情并不是那么简单

  • 不,不是真的


  • 那么,你是说从设计的角度来看,你会将存储库注入到服务中,而不是从存储库继承吗?这就是我在当前设计中所做的,是的。谁知道呢,随着时间的推移,这种味道可能会改变。但目前我在一个贫乏的领域模型中工作,虽然我的“服务”被称为“处理器”(因此不存在混淆,因为它们在实际服务后面),但想法基本上是相同的。如果你能找到一个令人信服的理由反对它,我很想知道,这样我就可以改进我自己的设计。我的博客(从我的个人资料链接而来)是探索这一点的一个个人出发点,尽管目前还处于起步阶段。我想这是有意义的,因为继承了乔的遗产