Writing Attributes and Extension Methods for Dynamic Data (original) (raw)

This is just a short article on some useful tips I’ve found for writing Attributes for Dynamic Data.

I say Tips there really isn’t that much to this.

Let me show you an attribute I just created for a post on the Dynamic Data Forum:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public class DisableEditingAttribute : Attribute { public Boolean Disable { get; set; }

public static DisableEditingAttribute Default = new DisableEditingAttribute();

public DisableEditingAttribute() : this(false) { }

public DisableEditingAttribute(Boolean disable)
{
    Disable = disable;
}

}

Listing 1 – Disable Editing Attribute

And here’s it being used in the List page:

protected void Page_Load(object sender, EventArgs e) { table = GridDataSource.GetTable(); Title = table.DisplayName;

//GridView1.Sort("ColumnName, ColumnName", SortDirection.Descending);

InsertHyperLink.NavigateUrl = table.GetActionPath(PageAction.Insert);

// Disable various options if the table is readonly
**_var editingDisabled = table.Attributes.OfType<DisableEditingAttribute>().DefaultIfEmpty(new DisableEditingAttribute()).FirstOrDefault();_**
if (table.IsReadOnly **_|| editingDisabled.Disable_**)
{
    GridView1.Columns[0].Visible = false;
    InsertHyperLink.Visible = false;
}

}

Listing 2 – DisableEditingAttribute in use BOLD ITALIC

The first ting to note is a Linq thing; the DefautIfEmpty extension method. This is used to specify a default value if the returned value is null (From the OfType FirstOrDefault combination) this means I don’t have to test for null like:

// Disable various options if the table is readonly var editingDisabled = table.Attributes.OfType().FirstOrDefault(); if (table.IsReadOnly || (editingDisabled != null && editingDisabled.Disable)) { GridView1.Columns[0].Visible = false; InsertHyperLink.Visible = false; }

Listing 3 – Having to test for null

Another way of doing this would be to use a Default static method to provide the default value.

// Disable various options if the table is readonly var editingDisabled = table.Attributes.OfType(). DefaultIfEmpty(DisableEditingAttribute.Default).FirstOrDefault(); if (table.IsReadOnly || editingDisabled.Disable) { GridView1.Columns[0].Visible = false; InsertHyperLink.Visible = false; }

Listing 4 – using the Default static method

Either method works but my preference is to have a default constructor Attribute() and I’ll explain why. But first let me show you an Extension method I found in the Dynamic Data Futures project extension methods:

public static T GetAttribute(this MetaTable table) where T : Attribute { return table.Attributes.OfType().FirstOrDefault(); }

Listing 5 – the GetAttribute Generic extension method.

And it’s use:

// Disable various options if the table is readonly var editingDisabled = table.GetAttribute(); if (table.IsReadOnly || (editingDisabled != null && editingDisabled.Disable)) { GridView1.Columns[0].Visible = false; InsertHyperLink.Visible = false; }

Listing 6 – the GetAttribute extension method in use

This is better more readable code but the test for null makes it a bit messy. So here are my interpretations of the GetAttribute extension method:

public static T GetAttributeOrDefault(this MetaTable table) where T : Attribute, new() { return table.Attributes.OfType().DefaultIfEmpty(new T()).FirstOrDefault(); }

public static T GetAttributeOrDefault(this MetaColumn column) where T : Attribute, new() { return column.Attributes.OfType().DefaultIfEmpty(new T()).FirstOrDefault(); }

Listing 7 – My GetAttributeOrDefault extension methods

All I’ve done here is use the DefaultIfEmpty Linq extension method and added an extra constraint to the generic class the make the extension method only work with attributes that have an explicit default Constructor.

And just for completeness here are all the generic extension methods together:

public static T GetAttributeOrDefault(this MetaTable table) where T : Attribute, new() { return table.Attributes.OfType().DefaultIfEmpty(new T()).FirstOrDefault(); }

public static T GetAttribute(this MetaTable table) where T : Attribute { return table.Attributes.OfType().FirstOrDefault(); }

public static T GetAttributeOrDefault(this MetaColumn column) where T : Attribute, new() { return column.Attributes.OfType().DefaultIfEmpty(new T()).FirstOrDefault(); }

public static T GetAttribute(this MetaColumn column) where T : Attribute { return column.Attributes.OfType().FirstOrDefault(); }

Listing 8 – All Generic Attributes together

The one in BOLD ITALIC is the original from Dynamic Data Futures project.

I think C# 3.0 is real neat HappyWizard