Creating a New Matching Rule

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.

The Unity Application Block defines an interface named IMatchingRule, which all classes that implement matching rules must implement. This interface declares a single method named Matches that takes a MethodBase instance and returns a Boolean value.

public interface IMatchingRule
  bool Matches(MethodBase member);

Inside a concrete implementation of this interface, a custom matching rule class can access details of the current member (method or property) of the target object and determine whether the Unity Application Block should add a handler pipeline to this member. The Matches method should return True if the current member matches the requirements of this matching rule; if the current member does not match the requirements of this matching rule, it should return False.

Remember that there may be several matching rules defined for a policy, and every one must return True when the Unity Application Block calls their Matches method in order for the application block to add the handler pipeline to the target class member.

As an example of a matching rule, this following extract shows the TagAttributeMatchingRule class that implements the built-in Tag Attribute Matching Rule. This rule examines the current target object member, passed to the Matches method as a parameter, looking for any attributes of type TagAttribute, whose value matches the string value passed to the class constructor.

public class TagAttributeMatchingRule : IMatchingRule
  private readonly string tagToMatch;
  private readonly bool ignoreCase;

  // This constructor takes only the tag value.  
  public TagAttributeMatchingRule(string tagToMatch)
       : this(tagToMatch, false)
  { }

  // This constructor takes the tag value and the case-sensitivity setting. 
  public TagAttributeMatchingRule(string tagToMatch, bool ignoreCase)
    this.tagToMatch = tagToMatch;
    this.ignoreCase = ignoreCase;

  // The returns true only if a matching TagAttribute exists on this member.
  public bool Matches(MethodBase member)
    foreach (TagAttribute tagAttribute in 
             ReflectionHelper.GetAllAttributes<TagAttribute>(member, true))
      if (string.Compare(tagAttribute.Tag, tagToMatch, ignoreCase) == 0)
        return true;
    return false;

When the Unity Application Block factory class first creates an instance of the target object, it reads a list of matching rules from the configuration. For each rule it finds, it creates an instance of the appropriate class and passes to it as parameters the values of any attributes defined within the configuration for that matching rule. You can see that the constructors for the TagAttributeMatchingRule class accept the name of the attribute and a case-sensitivity value.

Internally, the TagAttributeMatchingRule class uses a separate helper class named ReflectionHelper that gets a list of all the attributes of type TagAttribute on the target member, so that the Matches method can detect any that has the specified value—taking into account the setting of the ignoreCase property for this handler instance.

Notice that the TagAttributeMatchingRule class has a ConfigurationElementType attribute that defines the class (TagAttributeMatchingRuleData) that the configuration system uses to expose the data from the configuration to the matching rule. As an alternative approach, you can also use the CustomMatchingRuleData class in this attribute. This eliminates the need to create your own configuration data class; however, configuration information will be provided as a dictionary and will not be strongly typed.