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.

jason
  • 236,483
  • 35
  • 423
  • 525
Graviton
  • 81,782
  • 146
  • 424
  • 602
  • Is eligibility a compile time or runtime decision? – John Knoeller Dec 21 '09 at 01:27
  • What should happen if something attempts to call the method when it's not accessible? Exception thrown? Silent failure? Garbage result? – Anon. Dec 21 '09 at 01:27
  • If this is a compile time decision, then you can use the attribute '[Conditional("CONDITION1")]' – P.K Dec 21 '09 at 01:39
  • 3
    Unrelated to your question, I consider having a method called `CanAccessDatabase` that doesn't return anything to be a huge failure of naming standards. – Anon. Dec 21 '09 at 01:45
  • @PK: No, it's not a compile time decision. – Graviton Dec 21 '09 at 01:45
  • 1
    So the idea is that by adding an attribute to a method, you can get the compiler to automatically emit a bit of code either at the top of the function or whenever it's called? I had no idea that this was even possible... – John Knoeller Dec 21 '09 at 01:49
  • @Anon: Well, that `CanAccessDatabase` was a name that I conjured up while I was typing the question. The name was not even remotely connected with my *real* application. – Graviton Dec 21 '09 at 01:55

6 Answers6

3

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
  • 236,483
  • 35
  • 423
  • 525
  • ++ 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 Dec 21 '09 at 01:54
  • 2
    I hate to break the news, but Patterns and Practices stuff is not considered MS products. They may be built on top of MS products, by MS people, but they are not officially supported. WCSF was also put out by the P&P guys, and it is pretty much an abandoned framework at this point. PostSharp and Castle may very well have more community support than anything from the Patterns and Practices guys. – Josh Dec 21 '09 at 02:28
2

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.

Community
  • 1
  • 1
Mauricio Scheffer
  • 98,863
  • 23
  • 192
  • 275
  • Thanks, as I can use PostSharp or Castle, I would prefer something .Net framework built-in, i.e., not depending on third party libraries. – Graviton Dec 21 '09 at 01:37
  • @Ngu ALL of the Microsoft.Practices libraries are "third party" Just as previously stated in my other comment, they are not officially supported. – Josh Dec 21 '09 at 02:30
2

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
  • 60,973
  • 31
  • 151
  • 169
  • Thanks, you have any examples? so far all the examples I got,none of them deal with precondition check. – Graviton Dec 21 '09 at 01:38
  • 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. – Graviton Dec 21 '09 at 01:48
  • @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 Dec 21 '09 at 01:53
2

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
  • 380,855
  • 102
  • 628
  • 825
1

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
}
Chuck Savage
  • 11,775
  • 6
  • 49
  • 69
0

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

Muhammad Soliman
  • 21,644
  • 6
  • 109
  • 75