PostSharp provides several custom attributes that you can apply to your object model to describe the parent-child relationships in a natural and concise way. The AggregatableAttribute aspect is applied to the object model classes, and the properties are marked with ChildAttribute, ReferenceAttribute and ParentAttribute custom attributes. You can also use AdvisableCollection<T> and AdvisableDictionary<TKey, TValue> classes to make your collection properties aware of the Aggregatable pattern.
The following procedure shows how to add parent-child relationships to existing object models.
Applying the Aggregatable pattern to an object model
Add the
PostSharp.Patterns.Aggregationpackage to your project.Add the AggregatableAttribute aspect to all base classes. Note that the aspect is inherited, so it is not necessary to explicitly add the aspect to classes that derive from a class that already has the aspect. Note also that the AggregatableAttribute aspect is implicitly added by other aspects, including all threading models (ThreadAwareAttribute), DisposableAttribute and RecordableAttribute.
Note
It is not strictly necessary to add the AggregatableAttribute aspect to a class whose instances will be children but not parents unless you want to track the relationship to the parent using the Parent property or the ParentAttribute custom attribute in this class (see below).
Annotate fields and automatic properties of all aggregatable classes with the ChildAttribute or ReferenceAttribute custom attribute. Fields or properties of a value type must not be annotated.
Collections require special attention:
Modify the code to use AdvisableCollection<T>, AdvisableDictionary<TKey, TValue> or AdvisableKeyedCollection<TKey, TItem> instead of standard .NET collections for child fields. This change is necessary because all objects assigned to child fields/properties must be aware of the Aggregatable pattern.
By default, the items of a child collection are children of the object that owns the collection. If the collection itself is a child but its items should be considered as references, set the ItemsRelationship property to
RelationshipKind.Reference.
See Working With Child Collections for details.
Optionally, add a field or property to link back from the child object to the parent, and add the ParentAttribute to this field/property. PostSharp will automatically update this field or property to make sure it refers to the parent object.
Tip
For better encapsulation, setters of parent properties should have
privatevisibility. In case of parent fields, theprivatevisibility is preferred. User code should not manually set a parent field or property.
Example
In the following example, an Invoice object owns several instances of the InvoiceLine class, therefore both classes must be annotated with AggregatableAttribute. However, the Invoice does not own the Customer to which it is associated, so the Customer class does not need the custom attribute.
Note that in the constructor of the Invoice class, we assign an AdvisableCollection<T> to the Lines field instead of a List.
[Aggregatable]
public class Invoice
{
public Invoice()
{
this.Lines = new AdvisableCollection<InvoiceLine>();
}
[Reference]
public Customer Customer { get; set; }
[Child]
public IList<InvoiceLine> Lines { get; private set; }
[Child]
public Address DeliveryAddress { get; set; }
}
[Aggregatable]
public class InvoiceLine
{
[Reference]
private Product product;
public decimal Amount { get; set; }
[Parent]
public Invoice ParentInvoice { get; private set; }
}
[Aggregatable]
public class Address
{
}
public class Customer
{
}
See Also
Reference
AggregatableAttribute
ParentAttribute
ChildAttribute
ReferenceAttribute
AdvisableCollection<T>
AdvisableDictionary<TKey, TValue>
Other Resources