静态方法作为合约的一部分
我正在实现一个用于 Web 应用程序中模型访问控制的基础设施。该库有一个上下文类,控制器(也可能是视图)使用它来确定当前用户是否有权访问某个对象。为了使相关信息靠近目标对象,我决定将访问检查请求从上下文对象传递到模型本身。
实现这种模型对象修改机制几乎是微不足道的。声明一个接口,例如 ICheckModifyAccess
;并在您的模型中实现它。删除检查也是如此。在这两种情况下,都可以询问模型的实例是否可以修改或删除它们。
不幸的是,读取和创建操作并非如此。这些操作要求我向模型类提出问题。因此,为此使用接口并不是一种选择。
我最终创建了一个属性 CheckCreateAccessAttribute
,然后最终使用该属性将静态函数标记为接口函数。然后,在我的上下文对象中,我可以使用反射来检查这样的标记函数是否存在,它是否与我期望的签名匹配,并最终调用它。为了以防万一,创建访问检查的方法是 public bool CanCreate
[CheckCreateAccess]
public static bool CanCreate()
{
return true;
}
我对 C# 还不是很流利,而且我有一种挥之不去的感觉,我做错了什么。你能建议一个更优雅的选择吗?特别是,你能摆脱通过反射检查TObj
吗?
I am implementing an infrastructure for access control of models in a web application. The library has a context class that controllers (and maybe views) use for determining if the current user has access to a certain object. For keeping relevant information close to the target object, I've decided to pass on the access check request to the models themselves from the context object.
Implementing this mechanism for model object modification is almost trivial. Declare an interface, say, ICheckModifyAccess
; and implement it in your model. The same goes for delete check. In both these cases, it is possible to ask an instance of a model whether it is OK to modify or delete them.
Unfortunately, it is not the case for read and create operations. These operations require that I ask the question to the model class. So using an interface for this is not an option.
I ended up creating an attribute, CheckCreateAccessAttribute
, and then ended up using this attribute to mark a static function as the interface function. Then, in my context object, I can use reflection to check if such a marked function exists, if it matches the signature I expect, and eventually call it. In case it makes a difference, the method for create access check is public bool CanCreate<TObj>();
. A typical model that supports access control would add something like the following to the class:
[CheckCreateAccess]
public static bool CanCreate()
{
return true;
}
I am not very fluent in C# yet, and I have a nagging feeling that I'm doing something wrong. Can you suggest a more elegant alternative? Especially, can you get rid of examining TObj
by reflection?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
听起来您已经将关注点合并到对象类中,而不是将它们分开。
“将相关信息保持在目标对象附近”的诱惑可能导致您采用这种结构。
也许您可以在单独的类中处理权限,例如,请参阅 这篇文章。
It sounds like you've combined concerns in your object classes instead of separating them.
The temptation to "keep relevant information close to the target object" has perhaps led you to this structure.
Perhaps you could instead handle permissions in a separate class, see for example this article.
我认为你不应该询问某个特定用户是否可以修改他(除非修改权是针对每个具体实体的)。只需创建一个处理权限的类(或使用适当的现有类)。
这将消除您对静态类和反射的需要。
如果您将有很多类型,并且每个类型都有自定义规则(即代码),那么您可以拥有一个通用抽象类型(接口或抽象类),它能够检查一种类型和某个存储库的规则检索特定实例。
I think you shouldn't ask some specific user whether you can modify him (unless the modify right is per concrete entity). Just create a class that handles the rights (or use appropriate existing class).
This would eliminate your need for static classes and reflection.
If you are going to have lots of types, with custom rules (i.e. code) for every one of them, you could have a generic abstract type (interface or abstract class) that is able to check the rules for one type and some repository to retrieve the specific instance.