Attribute-based Policy Injection

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 Enterprise Library information can be found at the Enterprise Library site.

A common scenario when using any policy injection framework is the requirement to specify policies for classes and their members using attributes directly applied to the appropriate classes and members. The Policy Injection Application Block supports this technique; this means the only configuration required is the addition of the application block to the Enterprise Library configuration for the application. After that, the application block actively discovers classes and members with the attributes defined within the Policy Injection Application Block applied, and then the application block applies the appropriate policies.

Developers specify handlers for classes and their members (methods and properties) using a series of attributes defined within the Policy Injection Application Block. Using directly applied attributes has the following advantages:

  • Developers can ensure that the application block adds handlers that are specifically required in all circumstances and which should never be removed from the handler pipeline.
  • Developers can "fix" the settings or values of specific parameters on classes and class members—for example, by defining that specific parameter values must always be greater than zero or that logging will always occur for specific methods.
  • Developers can prevent the application of a handler pipeline to specific methods and properties, or to whole classes, using the ApplyNoPolicies attribute.

However, applying policies through attributes applied directly to members of the target classes means that developers, administrators, and operators can no longer control the behavior of the Policy Injection Application Block without changing the source code and recompiling the solution. In addition, using the ApplyNoPolicies attribute may cause unexpected behavior for developers, administrators, and operators, who may attempt to add policies to an application without being aware of the applied attributes.

Note

The Validation Handler, Logging Handler, Authorization Handler, and Exception Handling Handler all invoke other Enterprise Library application blocks that require support from the configuration system. When applying these handlers using attributes, these application blocks will always be initialized using the default configuration source. There is no support for using non-default configuration sources in this situation.

As an example of using directly applied attributes, if you use the methods of the Policy Injection Application Block factory class to create an instance of a class with the ValidationCallHandler attribute applied, the application block creates a handler pipeline that contains the ValidationCallHandler, which itself uses the features of the Enterprise Library Validation Application Block. The Validation Application Block then uses the settings you specify with attributes on the class members, or in a rule set defined within the Validation Application Block configuration, to perform the required validation.

The following code shows this in practice, where a method named Deposit uses the validators from the Validation Application Block to validate the value of the depositAmount parameter, ensuring that the value is greater than zero.

[ValidationCallHandler]
public void Deposit([RangeValidator(typeof(Decimal), "0.0", 
                     RangeBoundaryType.Exclusive, "0.0", 
                     RangeBoundaryType.Ignore)] decimal depositAmount)
{
  balance += depositAmount;
}
'Usage
<ValidationCallHandler> _
Public Sub Deposit(<RangeValidator(typeof(Decimal), "0.0", _
                    RangeBoundaryType.Exclusive, "0.0", _
                    RangeBoundaryType.Ignore)> Decimal depositAmount)
  balance += depositAmount
End Sub

Policy and Handler Precedence with Attributes

The Policy Injection Application Block combines all the policies it discovers for each class and class member. When classes and members use directly applied attributes to define the handlers for a class or class member, and the application configuration contains matching rules that select the same class or class member, the Policy Injection Application Block applies a set of precedence rules to determine the overall combined policy to apply.

The order of precedence for the discovery and application of handlers is the following:

  1. If the class or type, or any class or type in its inheritance hierarchy, has the ApplyNoPolicies attribute, the discovery process ceases and the application block does not apply any policies to that class or type.
  2. If the member (property or method) of the class, or in a class within its inheritance hierarchy, has the ApplyNoPolicies attribute, the discovery process ceases and the application block does not apply any policies to that member.
  3. If the class or type, or any class or type in its inheritance hierarchy, has any of the standard Policy Injection Application Block handler attributes, the application block applies these handlers and continues the discovery process. The final order of individual handlers is unspecified if you do not provide a value for the Order property of each one.
  4. If the member (property or method) of the class (or the same member in a class within its inheritance hierarchy) carries a handler attribute, the application block applies this handler and continues the discovery process. The final order of individual handlers is unspecified if you do not provide a value for the Order property of each one, although handlers for property accessors (Get and Set) usually occur earlier in the handler pipeline.
  5. If the configuration for the Policy Injection Application Block contains matching rules that select the class or member, the application block applies these handlers. However, it will not overwrite, change, or replace any handlers defined at higher precedence. The application block applies policies defined later in the configuration closer to the target (later in the handler pipeline) and applies handlers within each policy in the order they occur in the configuration or the order specified by for the Order property of each one.

For details about the Policy Injection Application Block handler attributes and their use, see Applying Handlers Using Target Member Attributes.