Tuesday, July 21, 2020

PostSharp [Aggregatable]

One of the things we have to work hard at is representing Parent/Child relationships in object trees. For example, we have documents and each document has a collection of details. We often need to hold a reference to the parent in each child. This allows us to pass the child object to a method and have the method browse to the parent. Postsharp allows us to do this easily.

Start a new console application in Visual Studio. I'm using 2019 with C#. Use the Nuget package manager to add PostSharp.Patterns.Model and installl it in your project. If you have a license, add the postsharp.config file now.


Now let's mock up some classes with a parent/child relationship in Program.cs

using PostSharp.Patterns.Collections;
using PostSharp.Patterns.Model;
using System;
using System.Collections.Generic;

namespace PostSharp2
{
    class Program
    {
        [Aggregatable]
        public class Document
        {
            public int ID { get; set; }
            public string Number { get; set; }

            [Child]
            public IList<Detail> Details { get; set; }

            public Document()
            {
                Details = new AdvisableCollection<Detail>();
            }
        }

        [Aggregatable]
        public class Detail
        {
            [Parent]
            public Document Document { get; set; }

            public int ID { get; set; }
            public string AccountNumber { get; set; }
            public decimal Amount { get; set; }
        }

        static void Main(string[] args)
        {
        }
    }
}
 .
We add the [Aggregatable] attribute to the parent and detail classes to indicate they take part in an aggregatable relationship. The detail collection is a new type of collection called AdvisableCollection. The Detail class has a Parent placeholder. We do not populate it - the AdvisableCollection's Add method does that.

Let's add some code to Main that populates and then interrogates our objects.

        static void Main(string[] args)
        {
            Document document = new Document() { ID = 1, Number = "A23" };
            Detail detail = new Detail() { ID = 2, AccountNumber = "XJ3-F", Amount = 100 };
            Console.WriteLine(string.Format("Before Add: Parent={0}", detail.Document?.Number));

            document.Details.Add(detail);
            Console.WriteLine(string.Format("After Add: Parent={0}", detail.Document?.Number));

        }

When we run this code we see that before we add the detail to the document's detail collection the detail's Parent is null, but afterwards it contains a reference to the document.



No comments:

Post a Comment