【问题标题】:Static method as part of a contract作为合约一部分的静态方法
【发布时间】:2011-12-04 03:00:29
【问题描述】:

我正在为 Web 应用程序中的模型实现访问控制的基础架构。该库有一个上下文类,控制器(可能还有视图)使用它来确定当前用户是否有权访问某个对象。为了将相关信息保持在目标对象附近,我决定将访问检查请求从上下文对象传递给模型本身。

为模型对象修改实施这种机制几乎是微不足道的。声明一个接口,比如ICheckModifyAccess;并在您的模型中实现它。删除检查也是如此。在这两种情况下,都可以询问模型实例是否可以修改或删除它们。

不幸的是,读取和创建操作并非如此。这些操作需要我向模型class提问。因此,为此使用接口不是一种选择。

我最终创建了一个属性CheckCreateAccessAttribute,然后最终使用该属性将静态函数标记为接口函数。然后,在我的上下文对象中,我可以使用反射来检查是否存在这样的标记函数,它是否与我期望的签名匹配,并最终调用它。万一有所不同,创建访问检查的方法是public bool CanCreate<TObj>();。支持访问控制的典型模型会在类中添加如下内容:

[CheckCreateAccess]
public static bool CanCreate()
{
    return true;
}

我对 C# 还不是很流利,而且我总感觉自己做错了什么。你能推荐一个更优雅的选择吗?特别是,你能摆脱通过反射检查TObj吗?

【问题讨论】:

  • 我不明白。为什么不能有一个模型实例来进行创建和读取操作?
  • 优雅,主要原因。例如,我想创建一个所有用户的列表。如果我把它放在一个接口中,为了检查读取权限,我需要实例化一个虚拟用户,询问我是否可以使用这个实例读取,然后继续创建列表,如果我被允许的话。通过上面的方法,我问我是否可以读取这个类的对象,然后读取它们。

标签: c# interface static-methods


【解决方案1】:

我认为您不应该询问某些特定用户是否可以修改他(除非修改权是针对具体实体的)。只需创建一个处理权限的类(或使用适当的现有类)。

这将消除您对静态类和反射的需求。

如果您将拥有许多类型,并且每个类型都有自定义规则(即代码),那么您可以拥有一个通用抽象类型(接口或抽象类),它能够检查一种类型的规则并一些用于检索特定实例的存储库。

【讨论】:

  • 这也是我们正在考虑的替代方法之一。这样做的缺点是,当您添加更多模型时,为每个人实现访问控制规则的类会变得更大。好处是,一切都简单、美观且集中。还有一些常见的规则,例如“用户可以修改自己的帖子,但不能修改其他人”。因此,在某些情况下,用于修改的 ACL 涉及查看模型的内部。所以询问模型本身看起来更合适。
【解决方案2】:

听起来您在对象类而不是 separating them 中合并了关注点。

“将相关信息保持在目标对象附近”的诱惑可能导致您采用这种结构。

也许您可以改为在单独的类中处理权限,例如参见this article

【讨论】:

  • 听起来不错。也许我可以创建一个实现默认访问控制规则的通用类,并为我的每个模型专门化它们(我是不是想太多 C++?)。或者我可以简单地听从 svick 的建议,把所有规则都扔到一个班级里。
  • 好文章链接。我希望我可以+2。它将帮助组织控制器上事物的使用方面。
  • 正如我所怀疑的,模板专业化是一种非常 C++ 的方式来做到这一点。我需要想出另一种方法。无论如何,关注点分离是一个非常好的建议。它消除了我的模型对象与此特定应用程序及其访问控制规则之间的耦合 - 允许它们在其他项目中重用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-02
  • 1970-01-01
  • 1970-01-01
  • 2015-10-17
  • 1970-01-01
  • 2012-10-12
  • 2020-03-06
相关资源
最近更新 更多