(WF4) Setting a default type parameter for Generic Activities added from the Toolbox

One of our internal customers pinged me with a quick question today. He asked whether it is possible to set a default type argument for T if you have an activity of GenericType, say DataCollectorActivity<T>.

I might have said this in passing by before but the answer is yes, the same technique is used for activities such as ForEach<T>.

The workflow designer will look for the attribute in the MetadataStore first before resorting to reflection, so there are 2 ways you can do it:

1. Quick and Dirty Way: Attributes in the code

    [System.Activities.Presentation.DefaultTypeArgument(typeof(int))]

    public class DataCollectorActivity<T> : CodeActivity

    {

        //...

    }

This is a nice quick-to-code solution because you can fit it all in one project. The downside to doing it this way is that it requires your runtime activity assembly to have a lot of big, chunky referenced assemblies like System.Activities.Presentation, PresentationFramework and PresentationCore that it doesn’t make sense to add if you can just avoid it by using IRegisterMetadata rhyming scheme instead.

2. Better Way: IRegisterMetadata in a .Design.dll and the MetadataStore

You can do it the same way as you would add a DesignerAttribute. Note that the syntax for getting the type of a pure generic type (instead of a subtype) is typeof(G<>), not typeof(G<T>).  (Remember, if you are shipping designers for use in VS and want the code below to be loaded and run automatically by Visual Studio every time you use the activity, then the code below has to be in YourAssemblyName.Design.dll, as per the above linked post.)

class Metadata : IRegisterMetadata

{

    public void Register()

    {

        AttributeTableBuilder builder = new AttributeTableBuilder();

       // Register Designers.

       builder.AddCustomAttributes(typeof(DataCollectorActivity<>), new DefaultTypeArgumentAttribute(typeof(int)));

       // Apply the metadata

      MetadataStore.AddAttributeTable(builder.CreateTable());

    }

}