views:

107

answers:

4

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 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.

+1  A: 

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.

Mauricio Scheffer
Thanks, as I can use PostSharp or Castle, I would prefer something .Net framework built-in, i.e., not depending on third party libraries.
Ngu Soon Hui
@Ngu ALL of the Microsoft.Practices libraries are "third party" Just as previously stated in my other comment, they are not officially supported.
Josh
+1  A: 

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
Ash
Thanks, you have any examples? so far all the examples I got,none of them deal with precondition check.
Ngu Soon Hui
I read your example; all it says is how to check the existence of the attribute of any method at runtime and work upon it. But that means that I would have to specifically write the mechanism for to check for the attribute and call the `Eligible` class before any method is executed. And that's the piece of code I hope is written already by Microsoft. All I have to do ( and all I ask here) is to find it out.
Ngu Soon Hui
@Ngu Soon Hui, yes, if you choose to do this yourself, you need to use reflection to first check for the attibute and then execute the method based on your custom logic. If you don't want to do this you should use an AOP frmaework. Microsoft don't currently provide AOP as part of the Framework C Library.
Ash
Correction in previous comment: Framework Class Library
Ash
+2  A: 

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).

Jason
++ for suggesting unity. I suspect the OP doesn't want 3rd party stuff due to corporate requirements. The company may be more comfortable with using an MS product.
Chad Ruppert
Josh
+1  A: 

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.

Lasse V. Karlsen