Creating a New Handler Attribute

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

The latest Unity Application Block information can be found at the Unity Application Block site.

Handler attributes allow developers to apply handlers to classes and class members directly, without configuring them in the application configuration file. Each handler included with the Unity Application Block has an equivalent handler attribute that applies the handler; for example, the ExceptionCallHandlerAttribute instantiates the Exception Handling Handler for the class or class members to which the attribute is applied.

Developers creating custom handlers may want to provide the equivalent attribute for their handlers. Alternatively, they may want to create attributes that apply one of the built-in handlers but set specific non-default properties. To build a custom handler attribute, you create a class that derives from the HandlerAttribute base class show here.

public abstract class HandlerAttribute : Attribute
{
  /// <summary>
  /// Derived classes implement this method. When called, it creates a 
  /// new call handler as specified in the attribute configuration.
  /// </summary>
  /// <returns>A new call handler object.</returns>
  public abstract ICallHandler CreateHandler();
}
'Usage
Public MustInherit Class HandlerAttribute : Inherits Attribute

  '''<summary>
  ''' Derived classes implement this method. When called, it creates a 
  ''' new call handler as specified in the attribute configuration.
  ''' </summary>
  ''' <returns>A new call handler object.</returns>
  Public MustOverride Function CreateHandler() As ICallHandler
End Class

In your custom attribute class, you must implement one or more constructors that accept values from the attribute, and/or implement named properties that the developer can use to set the properties of the class. Then you simply override the CreateHandler abstract method declared within the base class to create and return the required handler class as an ICallHandler instance. As an example, the following extract shows the CachingCallHandlerAttribute provided with the Policy Injection Application Block.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Method)]
public class CachingCallHandlerAttribute : HandlerAttribute
{
  private TimeSpan expirationTime;

  public CachingCallHandlerAttribute()
  {
    expirationTime = CachingCallHandler.DefaultExpirationTime;
  }

  public CachingCallHandlerAttribute(int hours, int minutes, int seconds)
  {
    expirationTime = new TimeSpan(hours, minutes, seconds);
  }

  public override ICallHandler CreateHandler()
  {
    return new CachingCallHandler(expirationTime);
  }
}
'Usage
<AttributeUsage(AttributeTargets.Class Or AttributeTargets.Property Or AttributeTargets.Method)> _
Public Class CachingCallHandlerAttribute : Inherits HandlerAttribute

    Private expirationTime As TimeSpan

    Public Sub New()
        expirationTime = CachingCallHandler.DefaultExpirationTime
    End Sub

    Public Sub New(ByVal hours As Integer, ByVal minutes As Integer, ByVal seconds As Integer)
        expirationTime = New TimeSpan(hours, minutes, seconds)
    End Sub

    Public Overrides Function CreateHandler() As ICallHandler
        Return New CachingCallHandler(expirationTime)
    End Function
End Class

Notice the AttributeUsage attribute that specifies where developers can apply the new custom attribute (on a class, a property, or a method), and—in this case—the provision of two constructors. The first (default) constructor uses the default expiration time specified by the CachingCallHandler class, while the second accepts values for the hours, minutes, and seconds, and generates an expiration time from these. The CreateHandler method override instantiates the CachingCallHandler class with the appropriate expiration time and returns this as an ICallHandler reference.