【问题标题】:Adding methods to POCO classes向 POCO 类添加方法
【发布时间】:2012-01-22 00:58:43
【问题描述】:

我有以下设置:MVC > 服务 > 存储库。现在我想让用户能够向文档添加注释。只有与文档关联的用户(作为所有者或审阅者)才能添加注释,因此在我的 NoteService 中,我执行以下操作以确保用户对所选文档具有权限:

public Note GetNewNote(int documentID)
    {
        if (!userHasAccess(Thread.CurrentPrincipal.Identity.Name))
            throw new BusinessLogicException();

        // Other stuff here...
    }

我的问题是,我应该在哪里定义 userHasAccess 方法? NoteService 在检查文档时没有任何意义。我可以在 DocumentService 中定义它,但是 NoteService 需要访问它,这似乎引入了更多的耦合。

对我来说,在 Document POCO 本身上定义它然后调用 document.userHasAccess(...) 更有意义。这是一种好的做法,还是应该将域 POCO 限制为简单的属性?我担心这确实是验证的一部分,并且通过将方法放在 POCO 中,我将 Service 和 POCO 之间的验证分开。

我要确保我的应用程序易于维护和测试。任何关于我应该如何解决这个问题的建议都将不胜感激!

【问题讨论】:

  • userHasAccess 做了哪些检查?代码访问安全性可能对您有用。
  • 它只是检查用户是否在 Document.Owners 或 Document.Reviewers 中 - 这些是 Document 和 Person 之间的多对多关系。

标签: asp.net-mvc asp.net-mvc-3 validation poco


【解决方案1】:

我应该在哪里定义 userHasAccess 方法?

与设计的其余部分保持一致是有意义的,虽然我不知道完整的设计,但我至少可以说 POCO 本身上称为 UserHasAccess() 的方法是有意义的。

是否应该将域 POCO 限制为简单属性?

不,域 POCO 应该包含与对象相关的逻辑(尤其是验证逻辑)。否则,它最终会成为object with no behaviour - 您绝对应该避免这种情况。

但是,不要混淆域(业务)对象和视图对象,它们通常包含很少的逻辑。

您担心您将验证分开 服务和 POCO。

我会将验证放在 POCO 中,并将跨域逻辑放在服务中。

【讨论】:

  • 感谢您的回答和链接。只是为了进一步推动这一点,POCO 中倾向于进行什么样的验证?是不是像我的示例中那样,然后由服务调用的简单方法?所以一个服务可以调用它需要的那些来确定是否应该向控制器抛出一个验证异常(或其他什么)?或者我的 POCO 上应该有某种验证方法吗?
  • 我会在每个 POCO 上都有一个验证方法 - POCO 知道它是否有效是有道理的。不过,您的示例有点不同,作为一种方法本身是有意义的。
  • 验证方法的想法让我感到困惑,因为不同的服务方法需要不同的东西才能调用 POCO 有效。在我的示例中,userHasAccess 只是询问 POCO 我们是否可以做某事,而我认为的 validate 方法会进行诸如“用户名必须是唯一的”之类的检查。这不是开始将 POCO 与 EntityFramework 联系起来吗?
  • 在 POCO 上使用单一验证方法的问题在于,您可能需要验证多个操作。插入数据库是否有效?修改有效吗?如果您开始添加多个验证方法,那么您的 POCO 将开始承担多项职责。我更喜欢将验证逻辑放在单独的类中。
  • @epignosisx - validate 方法肯定会有不止一个动作 - 例如信用卡是否具有有效的开始/到期日期、卡类型的有效卡号...这些都将在返回多个验证消息的单个验证方法中。
【解决方案2】:

任何域实体也可以包含验证方法。

【讨论】:

  • 这是个好习惯吗?我不想开始将这些看似简单的方法添加到我的 POCO 类中,但后来发现它变得难以维护/测试。将所有验证保留在一个部分中会很好 - 在上面的示例中,我可以检查用户是否在 document.Owners 中,然后是否在 document.Reviewers 中,但我需要重复这个逻辑一次又一次,所以它需要有自己的方法。
  • James,正如 Joe 在他的回答中提到的,您可以将验证放在 POCO 中,并将跨域逻辑放在服务中。
【解决方案3】:
  1. 如果您遵循域模型模式,则可以添加带有行为的属性。 通过Martin fowler检查
  2. 如果您遵循表模块模式,则在 BLL 类中添加行为并在 POCO 中添加属性 也可以通过Martin fowler 进行检查

【讨论】:

    猜你喜欢
    • 2013-01-03
    • 2011-05-23
    • 1970-01-01
    • 1970-01-01
    • 2015-11-09
    • 2016-04-08
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多