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.
Below you can find a detailed walkthrough on how to add parent-child relationships implementation into existing object models.
To apply the Aggregatable to an object model:
Add the
PostSharp.Patterns.Model
package 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 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 children fields. This change is necessary because all objects assigned to children fields/properties must be aware of the Aggregatable pattern.
By default, PostSharp considers that items of child collections will be child objects of 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
private
visibility. In case of parent fields, theprivate
visibility is preferred. User code should not manually set a parent field or property.
Example
In the following examples, 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