开发者

Use Attributes To Check Whether to Access a Method

开发者 https://www.devze.com 2022-12-14 23:41 出处:网络
I have a method that is only accessible if a certain criteria is fulfilled, if it\'s not, then the method won\'t be executed. Currently, this is how I code the thing:

I have a method that is only accessible if a certain criteria is fulfilled, if it's not, then the method won't be executed. Currently, this is how I code the thing:

public void CanAccessDatabase()
{
   if(StaticClass.IsEligible())
   {
      return;
   }
   // do the logic
}

Now, this code is ugly because out of 开发者_JAVA百科no where there is this if(StaticClass.IsEligible()) condition that is not relevant to the concern of the method.

So I am thinking about putting the IsEligible method in the attribute, so that my code will look like this. If the condition is not fulfilled, then this method will just return without executing the logic below.

[IsEligibleCheck]
public void CanAccessDatabase()
{
   // do the logic
}

Eligibility is a runtime decision, of course.

Any idea on how to code up the logic for IsEligibleCheck ? Thanks

Edit: I know PostSharp can do this, but I am looking at something that works out of box, not depending on any third party library.


Any idea on how to code up the logic for IsEligibleCheck?

This is a perfect spot for AOP.

Edit: I know PostSharp can do this, but I am looking at something that works out of box, not depending on any third-party library.

Is Microsoft considered third-party? If not, you could look at Unity from their Patterns & Practices team. Look at the Interceptor mechanism in Unity.

Otherwise, you effectively have to roll your own implementation using reflection. Effectively what you have to do is wrap your objects in a proxy wherein the proxy uses reflection to check the attributes and interpret them appropriately. If IsEligibleCheck succeeds then the proxy invokes the method on the wrapped object. Really, it's easier to just reuse an already existing implementation.

My advice is just use Unity (or another AOP solution).


Unfortunately, attributes doesn't get executed at runtime. A handful of built-in attributes modify the code that gets compiled, like the MethodImpl attributes and similar, but all custom attributes are just metadata. If no code goes looking for the metadata, it will sit there and not impact the execution of your program at all.

In other words, you need that if-statement somewhere.

Unless you can use a tool like PostSharp, then you cannot get this done in out-of-the box .NET, without explicit checks for the attributes.


This looks like a perfect candidate for AOP. In a nutshell, this means that the CanAccessDatabase logic will live in an "aspect" or "interceptor", that is, separate from the business logic, thus achieving separation of concerns (the aspect is only responsible for security, business code is only responsible for business things).

In C#, two popular options for doing AOP are Castle.DynamicProxy and PostSharp. Each has its pros and cons. This question sums up their differences.

Here are other options for doing AOP in .Net, some of them can be done without 3rd-party libraries. I still recommend using either DynamicProxy, PostSharp, LinFu, Spring.AOP or Unity, other solutions are not nearly as flexible.


Custom attributes go hand in hand with Reflection.

You will need to create another class that is responsible for calling the methods in your CanAccessDatabase() class.

Using reflection, this new class will determine the attributes on each method. If the IsEligibleCheck attribute is found, it will perform the StatiClass.IsEligible() check and only call CanAccessDatabase() if the check passes.

Heres an introduction to doing this at MSDN. It revolves around using the MemberInfo.GetCustomAttributes() method.

Heres the pseudocode:

Get the Type of the CanAccessDatabase() class
Using this type, get all methods in this class (optionally filtering public, private etc).
Loop through the list of methods
    Call GetCustomAttributes() on the current method.
    Loop through the list of custom attributes
        If the IsEligibleCheck attribute is found
            If StaticClass.IsEligible is true
                Call the current method (using MethodInfo.Invoke())
            End If
        End If
    End Loop
End Loop


I know this is an old thread...

You can use the Conditional Attribute: http://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute.aspx

"Indicates to compilers that a method call or attribute should be ignored unless a specified conditional compilation symbol is defined."

#define IsEligibleCheck // or define elsewhere 

[Conditional("IsEligibleCheck")]
public void CanAccessDatabase()
{
   // do the logic
}


check AOP that will help you a lot in this, one of the powerful components in the market is PostSharp

0

精彩评论

暂无评论...
验证码 换一张
取 消