Understanding Attribute Multicasting |
This topic contains the following sections:
- Overview of the Multicasting Algorithm
- Filtering Target Elements of Code
- Filtering Properties
- Overriding Filtering Attributes

Every multicast attribute class must be assigned a set of legitimate targets using the MulticastAttributeUsageAttribute custom attribute, which is the equivalent and complement of AttributeUsageAttribute for multicast attributes. Multicast attributes can be applied to types, methods, fields, properties, events, or/or parameters. For instance, a caching aspect targets methods. A field validation aspect targets fields.
When a field-level multicast attribute is applied to a type, the attribute is implicitly applied to all fields of that type. When it is applied on an assembly, it is implicitly applied to all fields of that assembly.
The general rule is: when a multicast attribute is applied on a container, it is implicitly (and recursively) applied to all elements of that container.
The next table illustrates how this rule translates for different kinds of targets.
Directly applied to | Implicitly applied to |
---|---|
Assembly or Module | Types, methods, fields, properties, parameters, and events contained in this assembly or module. |
Type | Methods, fields, properties, parameters, and events contained in this type. |
Property or Event | Accessors of this property or event. |
Method | This method and the parameters of this method. |
Field | This field. |
Parameter | This parameter. |

Note that the default behavior is maximalistic: we apply the attribute to all contained elements. However, PostSharp provides a way to restrict the set of elements to which the attribute is multicast: filtering.
Both the attribute developer and the user of the aspect can specify filters.
Developer-Specified Filtering
Just like normal custom attributes should be decorated with the [AttributeUsage] custom attribute, multicast custom attributes must be decorated by the [MulticastAttributeUsage] attribute (see MulticastAttributeUsageAttribute). It specifies which are the valid targets of the multicast attributes.
For instance, the following piece of code specifies that the attribute GuiThreadAttribute can be applied on instance methods. Aspect users experience a build-time error when trying to use this aspect on a constructor or static method.
[MulticastAttributeUsage(MulticastTargets.Method, TargetMemberAttributes = MulticastAttributes.Instance)] [AttributeUsage(AttributeTargets.Assembly|AttributeTargets.Class|AttributeTargets.Method, AllowMultiple = true)] [PSerializable] public class GuiThreadAttribute : MethodInterceptionAspect { // Details skipped. }
Note the presence of the AttributeUsageAttribute attribute in the sample above. It tells the C# or VB compiler that the attribute can be directly applied to assemblies, classes, constructors, or methods. But this aspect will never be eventually applied to an assembly or a class. Indeed, the MulticastAttributeUsageAttribute attribute specifies that the sole valid targets are methods. Furthermore, the TargetMemberAttributes property establishes a filter that includes only instance methods.
Therefore, if the aspect is applied on a type containing an abstract method, the aspect will not be multicast to this method, neither to its constructors.
![]() |
---|
Additionally to multicast filtering, consider using programmatic validation of aspect usage. Any custom attribute can implement IValidableAnnotation to implement build-time validation of targets. Aspects that derive from Aspect already implement these interfaces: your aspect can override the method CompileTimeValidate(Object). |
![]() |
---|
As an aspect developer, you should enforce as many restrictions as necessary to ensure that your aspect is only used in the way you intended, and raise errors in other cases. Using an aspect in an unexpected way may result in runtime errors that are difficult to debug. |
User-Specified Filtering
The attribute user can specify multicasting filters using specific properties of the MulticastAttribute class. To make it clear that these properties only impact the multicasting process, they have the prefix Attribute.
As an aspect user, it is important to understand that you can only apply aspects to elements of codes that have been allowed by the developer of the aspect.
For instance, the following element of code adds a tracing aspect to all public methods of a namespace:
[assembly: Trace( AttributeTargetTypes="AdventureWorks.BusinessLayer.*", AttributeTargetMemberAttributes = MulticastAttributes.Public )]

The following table lists the filters available to users and developers of aspects:
MulticastAttribute Property | MulticastAttributeUsageAttribute Property | Description |
---|---|---|
Restricts the kinds of targets (assemblies, classes, value types, delegates, interfaces, properties, events, properties, methods, constructors, parameters) to which the attribute can be indirectly applied. | ||
Wildcard expression or regular expression specifying to which assemblies the attribute is multicast. | ||
Determines whether the aspect can be applied to elements defined in a different assembly than the current one. | ||
Wildcard expression or regular expression filtering by name the type to which the attribute is applied, or the declaring type of the member to which the attribute is applied. | ||
Restricts the visibility of the type to which the aspect is applied, or of the type declaring the member to which the aspect is applied. | ||
Wildcard expression or regular expression filtering by name the member to which the attribute is applied. | ||
Restricts the attributes (visibility, virtuality, abstraction, literality, ...) of the member to which the aspect is applied. | ||
Wildcard expression or regular expression specifying to which parameter the attribute is multicast. | ||
Restricts the attributes (in/out/ref) of the parameter to which the aspect is applied. | ||
Specifies whether the aspect is propagated along the lines of inheritance of the target interface, class, method, or parameter (see Understanding Aspect Inheritance). |
![]() |
---|
Whenever possible, do not rely on naming conventions to apply aspects (properties AttributeTargetTypes, AttributeTargetMembers and AttributeTargetParameters). This may work perfectly today, and break tomorrow if someone renames an element of code without being aware of the aspect. |

Suppose we have two classes A and B, B being derived from A. Both A and B can be decorated with MulticastAttributeUsageAttribute. However, since B is derived from A, filters on B cannot be more permissive than filters on A.
In other words, the MulticastAttributeUsageAttribute custom attribute is inherited. It can be overwritten in derived classes, but derived class cannot enlarge the set of possible targets. They can only restrict it.
Similarly (and hopefully predictably), the aspect user is subject to the same rule: she can restrict the set of possible targets supported by the aspect, but cannot enlarge it.