Rules always belong to an *IApiCop* instance. Rules are registered once and then updated when needed, based on the requirement of the rule. Rules are normally custom-made, but Catel does provide a few base implementations.

Registering rules

To register a rule in the IApiCop, use the following code:

ApiCop.RegisterRule(new UnusedFeatureApiCopRule("UserControlLogic.InfoBarMessageControl", "The InfoBarMessageControl is not found in the visual tree. This will have 
    a negative impact on performance. Consider setting the SkipSearchingForInfoBarMessageControl or DefaultSkipSearchingForInfoBarMessageControlValue to true.", 
    ApiCopRuleLevel.Error, ""));

The first argument is the name of the rule. This is a unique identifier and allows users to ignore rules by this name. The next parameter is a good extension which will explain to the end-developer what is wrong and why the rule is created in the first place. In this case it is about the InfoBarMessageControl which might have a negative impact on performance.

It is good practice to use the ClassName.FeatureName for the rule names

Updating rules

Once a rule is registered, it must be updated to actually provide any useful information. How a rule must be updated depends on the rule implementation, but the code below shows how the feature can be used. This specific rule is implemented to check if the InfoBarMessageControl is actually used by the software. If it is, the counter is increased as “feature being used”, otherwise “feature not being used”.

_infoBarMessageControl = FindParentByPredicate(TargetControl, o => o is InfoBarMessageControl) as InfoBarMessageControl;

    rule => rule.IncreaseCount(_infoBarMessageControl != null, TargetControlType.FullName));

This code shows the regular code executed by the framework (the search in the visual tree) and the update of the rule. Note that the update method only requires the following things: the name, a callback method and a tag. The reason a callback method is being used is that the callback will only be executed when a debugger is attached to minimize the impact on performance in production scenarios.

It is good practice to use the final class name as as tag (especially when the rule is registered in a base class)

Available rules

Catel provides the following rules out of the box.


This rule contains several counters. Each time code is executed, one must call the IncreaseCount method and specify if the feature is being used.


    rule => rule.IncreaseCount(isFeatureBeingUsed));

Have a question about Catel? Use StackOverflow with the Catel tag!