Static method as part of a contract

I am implementing an infrastructure for controlling access of models in a web application. The library has a context class that controllers (and possibly views) use to determine whether the current user has access to a specific object. To store relevant information close to the target, I decided to transfer the access control request to the models themselves from the context object.

The implementation of this mechanism to modify the model object is almost trivial. Declare an interface, say ICheckModifyAccess ; and implement it in your model. The same goes for delete verification. In both cases, you can ask the model instance whether it is normal to modify or delete them.

Unfortunately, this is not the case for read and create operations. These operations require me to ask a question to the model class. Therefore, using an interface for this is not an option.

As a result, I created the CheckCreateAccessAttribute attribute, and then used this attribute to designate a static function as an interface function. Then, in my context object, I can use reflection to check if such a marked function exists if it matches the expected signature and, ultimately, calls it. In case it matters, the method for creating an access check is public bool CanCreate<TObj>(); . A typical model that supports access control will add something like the following to the class:

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

I'm not very sure about C # yet, and I have the feeling that I'm doing something wrong. Can you offer a more elegant alternative? In particular, can you get rid of studying TObj reflection?

+4
source share
2 answers

It looks like you combined problems in your object classes, rather than separating them .

The temptation to β€œkeep relevant information close to the target” may have led you to this structure.

Perhaps you could handle permissions in a separate class, see, for example, in this article .

+2
source

I think you should not ask a specific user if you can change it (if the right to change is not specified in a specific object). Just create a class that handles rights (or uses the corresponding existing class).

This eliminates the need for static classes and reflection.

If you have many types with custom rules (for example, code) for each of them, you can have a common abstract type (interface or abstract class) that can check the rules for one type and some repository to get a specific instance.

+2
source

All Articles