Attributes

If you've done much .NET programming, you've probably used .NET attributes . If nowhere else, you've already seen them used a few times in this book! Attributes are metadata that can be applied to an assembly, a class, a method, or a variable. This metadata can be used by Visual Studio .NET, the compiler, or the .NET runtime to alter how our code is used or acts.

The .NET Framework uses attributes extensively, and we'll use them as we create our framework. We'll also be creating our own [Transactional()] attribute, so that we can tell our DataPortal whether to run our data-access methods in a context that's protected by transactions. Attributes are perfect for this sort of thing, because they're easy for developers to use, and they help to make business code self-documenting .

As we've seen, using them is pretty straightforward, as shown here:

  [Serializable()]  public class TheClass 

It's immediately obvious that this class is serializable. Suitably named attributes are intuitive, both to the initial developer and to any maintenance developers who may work with the code in the future.

Creating Custom Attributes

To augment the built-in attributes, as suggested earlier, we can create our own custom attributes. To do this, we just need to create a class that inherits from the System.Attribute base class in the .NET Framework.

Simple Attributes

The simplest kind of attribute we can create is one that takes no parameters as follows :

  public class TransactionalAttribute : Attribute   {   }  

We can then apply this attribute to anything we like. Note that our attribute's full name is TransactionalAttribute , but we only use [Transactional()] when applying it to our code, as shown here:

  [Transactional()]  public class Test {  [Transactional()]  string _name;  [Transactional()]  public void DoWork() 

Restricting Attribute Usage

In many cases, we'll want to place restrictions on where the attribute can be applied. To do this, we need to add an attribute to our attribute code!

  [AttributeUsage(AttributeTargets.Method)]  public class TransactionalAttribute : Attribute   {   } 

With this change, our attribute can no longer be applied to anything but a method. Placing it elsewhere will cause a compile-time error.

Detecting Custom Attributes

Creating and applying custom attributes is novel , but it doesn't really get us anywhere ” we also need a way to determine whether an attribute has been applied. It turns out that this is yet another trick that can be performed by reflection. Earlier, we discussed the use of reflection to get information about methods and fields, but retrieving attribute information is just an extension of those concepts. For example, suppose that we've defined a simple attribute that can be applied to methods, as follows:

 [AttributeUsage(AttributeTargets.Method)]   public class TransactionalAttribute : Attribute   {   } 

Given this, we can write code using reflection to find out if any method has this attribute applied to it, as shown here:

  private bool IsTransactional(MethodInfo method)     {       return Attribute.IsDefined(method, typeof(TransactionalAttribute));     }  

All we need to do is pass a MethodInfo object that corresponds to a method, and the function will return true if the method has the [Transactional()] attribute applied. To achieve this, it calls the static IsDefined method on the System.Reflection.Attribute class.

Defining and detecting custom attributes is a powerful technique for building frameworks and other reusable code in .NET. Once a custom attribute is defined, we can construct code that checks for its presence or absence, and then we can alter behavior based on that knowledge. From that point forward, anyone wishing to use our framework can simply apply attributes to their code in order to achieve the desired behavior.



Expert C# Business Objects
Expert C# 2008 Business Objects
ISBN: 1430210192
EAN: 2147483647
Year: 2006
Pages: 111

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net