Applying the AttributeUsageAttribute
The next step is to let .NET know that this class is an attribute and how this attribute can be used. This is accomplished by applying the AttributeUsageAttribute to our custom attribute.
The AttributeUsageAttribute has one positional argument and two named arguments. Positional arguments are simply arguments to the constructor that you want the consumer to supply, and named arguments represent properties that are optional. We can supply these values when we apply the attribute. The AttributeUsageAttribute's positional argument is the ValidOn argument, which is satisfied with the AttributeTargets enumerated values. The two named arguments are Inherited and AllowMultiple. Each argument is explained briefly in the following section, and this part of the discussion wraps up with an update to our code from Listing 1.
Expressing Attribute Applicability (ValidOn)
The constructor has one required, positional argument, named ValidOn. ValidOn is a bitwise value expressed by Or'ing AttributeTargets enumerated values together. For example, you pass AttributeTargets.All to indicate that your attribute is applicable to any element in a class. We want our attribute to be applied to properties only, so we'll apply the AttributeTargets.Property value to the AttributeUsageAttribute. For example, if you want to allow the attribute to be used on properties and fields, you could pass AttributeTargets.Property Or AttributeTargets.Property to AttributeUsageAttribute, indicating the multiple applicability election.
Expressing Inheritance (Inherited)
Inherited is defined as a property in the AttributeUsageAttribute. However, when you apply an attribute, the only chance you get to supply property values is to express them as named arguments. Named arguments, as the name suggests, are supplied by passing both the name and the value.
Attributes are inherited by default. If you don't want to allow child classes to inherit the attribute, you can pass false for the Inherited argument. At the end of the next section, I'll explicitly pass all three arguments to the revised code to show you how they're applied (see Listing 2).
Expressing Multiplicity (AllowMultiple)
AllowMultiple is another named argument, false by default. It indicates whether a particular attribute can be applied more than once to a single element. Because our example defines an attribute to help a fictitious application generator, we may want to generate both Windows Forms applications and Web Forms applications. We could justify applying the attribute twice: once for Windows Forms and once for Web Forms.
Listing 2 provides a verbose application of the AttributeUsageAttribute to our attribute class, demonstrating how to pass positional and named arguments. (We're ignoring the redundant use of Inherited because we're passing the default value for Inherited to the AttributeUsageAttribute constructor.)
Listing 2Applying the AttributeUsageAttribute to Our Custom Attribute
<AttributeUsage(AttributeTargets.Property, _ Inherited:=True, AllowMultiple:=True)> _ Public Class ControlDesignerAttribute End Class
As defined, our attribute can be applied only to properties, is inherited, and can be applied multiple times to the same element.