Attributes in Custom Objects

The approach to using the AOM Property model was this: I have a MetadataEntity object, which contains an attributes collection of type MetadataAttributeCollection, a collection of MetadataAttribute classes.  This MetadataAttribute class has a Name, Type, and Value property, which contains the information stored as the attribute.  I also include a generic method to get the strongly-typed version of the value:

public T GetValue<T>()
{
    if (this.Value != null)
        return (T)this.Value;
    return default(T);
}

The collection is a straight-forward collection, with some validation to ensure that when adding an item, that there isn't a duplicate item (an item with the same name) already in the list.  If there is, an error is thrown.  To determine the name, I added a default property that takes a parameter of name, and gets the object, if found:

public MetadataAttribute this[string name]
{
    get
    {
        foreach (MetadataAttribute attribute in this)
        {
            if (string.Compare(name, attribute.Name, true) == 0)
                return attribute;
        }

        return null;
    }
}

Also, for the sorting, I override the Compare method (as mentioned in my previous post), with this method:

public override int Compare(MetadataAttribute x, MetadataAttribute y)
{
    return x.Name.CompareTo(y.Name);
}

This method compares the metadata by the name, and sorts them this way by default, so they appear in order by name.  I also provide a generic method to get the value of a named metadata attribute, using the default property to get the metadata object by name, if it exists.  If it does, then it returns the value; otherwise, null is returned.

The MetadataEntry class exposes these properties through a property, which the collection is lazy-loaded (loaded when it is referenced):

public MetadataAttributeCollection Attributes
{
    get
    {
        if (_attributes == null)
            _attributes = new MetadataAttributeCollection();
        return _attributes;
    }
}

However, in this instance, it is loaded in the constructor, so lazy-loading really isn't a feature.  The constuctor takes the name as a parameter and assigns it to the collection:

public MetadataEntry(string name)
{
    //Add the initial name attribute
    this.Attributes.Add(new MetadataAttribute("Name", name));
}

Using the collection, you can create properties defined in the class, as I did for the Name property:

public string Name
{
    get { return this.Attributes.GetValue<string>("Name"); }
    set { this.SetAttributeValue("Name", value); }
}

This property returns the Name attribute value stored in the class; however, it isn't recommended to do this.  You lose the easier maintenance approach whenever you upgrade the application this way.  But, for Name, which is a common property across all objects, I did it this way.  SetAttributeValue is a helper method; if the name is null, it adds the name/value to the collection; otherwise, the existing attribute value is overwritten with the new value.

These objects will be featured in the next test.
 

Comments

No Comments