【问题标题】:Repository in Controller or Model?控制器或模型中的存储库?
【发布时间】:2009-05-15 22:02:28
【问题描述】:

我一直在研究 NerdDinner 教程,其中大部分内容都很有意义。我不确定的是为什么直接在控制器中使用存储库而不是模型对象。例如,如果我们想实现自己的会员系统,并且它有一个带有 Login 方法的 AccountController,那么连接它的最佳解决方案是什么?例如

Login(username,password){

    repo = AccountRepository

    account = repo.getLogin(username,password)

    //check account isn't locked

    //check account has been verified etc etc 

    //throw error or proceed to secure area

}

Login(username,password){

    repo = AccountRepository

    account = repo.getLogin(username,password)

    account.login() //business logic is handled in Account (Model)

}

Login(username,password){

    //no reference to repository

    account = Account

    //Account (Model) uses repository and handles business logic
    account.login(username,password) 

}

我建议让 Account 对象直接使用 AccountRepository,而不是 AccountController 从 AccountRepository 获取信息,然后将其传递给 Account 对象,例如

NerdDinnner 风格:

1 个登录请求进来
2 AccountController 使用 AccountRepository 根据请求获取登录详细信息
3 AccountController 使用 Account 对象并从第 1 步传入信息
4 Account对象处理请求并通知AccountController

我的建议:

1 个登录请求进来
2 AccountController根据请求使用Account对象处理登录
3 Account对象使用AccountRepository获取登录详情
4 Account对象处理请求并通知AccountController

后一种风格的原因是,在从 AccountRepository 返回登录详细信息后,将遵循业务规则,例如是否已锁定帐户,是否已验证帐户等 如果使用第一种样式,则获取详细信息然后使用它们的逻辑分为 2 个步骤。后一种风格将所有逻辑保持在一起,同时仍使用 AccountRepository,例如

Account.Login(username,password){
    repo = AccountRepository

    account = repo.GetLogin(username,password)

    //check account isn't locked

    //check account has been verified etc etc

    //throw error or proceed to secure area
}

我希望这是有道理的。

【问题讨论】:

    标签: asp.net-mvc model controller repository-pattern


    【解决方案1】:

    mvc 中的“模型”是表示模型而不是域模型。您可以将 MVC 中的模型视为控制器用来为视图引擎提供数据的数据传输对象。 控制器是与服务层连接的唯一参与者。

    【讨论】:

    • 在 mvc 的最基本实现中,模型通常在一定程度上最终成为对域模型的最基本解释。这是您正在使用的对象。您是否选择使这些模型比您建议的 DTO 更智能,取决于您想要设计应用程序的程度。诚然,我们都应该为纯 SOC 努力,但有些应用程序并不需要那种复杂程度。
    • 在小域中表示模型和域模型可以相同。但是,如果您有一个丰富的域模型或一个服务驱动的应用程序,那么您最终只会得到简单的 DTO。
    • 看看serialseb.blogspot.com/2009/05/my-mvc-best-practices-talk.html 只是为了了解模型的极端使用情况。还不错:D
    【解决方案2】:

    您至少应该有另一个层(不是控制器)负责与存储库接口进行交互。 Thil 允许将 de UI(控制器是它的一部分)更改为另一个。这样一来,无论是命令行、桌面还是 Web 界面都没有关系。

    在 ASP.NET MVC 中,我更喜欢将模型(不是我的域模型,MVC 模型)放在单独的项目中,而不是放在 MVC 中。这允许与其他类型的 UI 共享 DTO(MVC 模型)。

    【讨论】:

      【解决方案3】:

      存储库是一个基础架构问题。你正在做的是让你的模型依赖于你的基础设施。这是一种落后的做法。这意味着如果您想做诸如使用依赖注入之类的事情,则必须从容器中解析模型,这对我来说没有多大意义。

      此外,重点并不是真正将所有东西都放在一个地方。您应该努力将您的关注点分成逻辑单元。通过这种方式,您可以轻松识别应用程序的哪些部分做了什么。它也适用于测试。

      【讨论】:

        【解决方案4】:

        我会说不是帐户执行登录,而是您使用帐户登录应用程序,因此在帐户上调用Login方法似乎有点不自然。

        在领域驱动设计中,有一个业务逻辑的位置不适合 Account 类:这称为服务。您可以阅读有关 DDD 服务的更多信息,例如here

        【讨论】:

          【解决方案5】:

          我会避免将您的数据访问权限放在您的模型中。这很可能导致模型依赖于存储机制。我通常会将此逻辑放在服务/业务逻辑层中,该层将与数据层和模型进行对话。在您只有模型和控制器的情况下,它将是执行此工作的控制器。

          我认为域模型是一组玩具或工具,您可以拿起、使用、操作等。玩具并不真正关心它们的存储位置,也不应该关心它们。您应该能够将玩具放在架子上或工具箱中。不影响玩具。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-10-18
            • 1970-01-01
            • 2011-10-15
            • 1970-01-01
            • 1970-01-01
            • 2018-10-25
            • 2010-12-15
            相关资源
            最近更新 更多