Search code examples
xamlworkflow-foundation-4workflow-foundation

WF4 Runtime attempts to load loosely coupled Activity Designer


I have created a custom code activity, also with a custom designer - which I have applied to the activity using the following convention

[Designer("MyDesignerType, Assembly, Version=1.0.0.0, PublicKeyToken=XXX")]

This works at design-time, my designer is loaded (if I place it in the GAC) and is used to display my activity on the design surface.

When I publish my workflow, the designer DLL is not on the production server (which is exactly what I intended - hence why I referenced the designer through the 'strong-name' version of the DesignerAttribute constructor, rather than creating a hard-link to the designer DLL).

HOWEVER, when the runtime loads the workflow on the production server - it's throwing a TypeNotFound Exception - attempting to load the MyDesignerType/DLL. WHY?? Why on earth is the workflow runtime trying to load a design-time functionality at runtime?? The whole reason that the DesignerAttribute comes with a loosely-coupled constructor is to avoid deploying designer DLLs with a product...

Any help would be greatly appreciated.

Thanks


Solution

  • If you want loose coupled Activity Designer you won't apply the DesignerAttribute at all.

    So basically, to support your scenario, you'll have 2 dlls like this:

    • MyProject.Activities.dll
    • MyProject.Activities.Design.dll

    The key part here is the Design.dll. Within that dll you should have a class implementing IRegisterMetadata and that's where magic happens.

    IRegisterMetadata types provide a way to encapsulate the association of design-time attributes to run-time types in a loosely coupled fashion. An application hosting the Windows Workflow Designer can use the IRegisterMetadata interface to register the attributes for the activity. For instance, Visual Studio 2010 searches for types that implement IRegisterMetadata when assemblies that contain these types are loaded in addition to also looking for types in the *.design assemblies.

    How to register a designer on an activity through IRegisterMetadata:

    class Metadata : IRegisterMetadata
    {
        public void Register()
        {
            AttributeTableBuilder builder = new AttributeTableBuilder();
            // Register Designers.
            builder.AddCustomAttributes(typeof(MyActivity), new DesignerAttribute(typeof(MyActivityDesigner)));
            // Apply the metadata
            MetadataStore.AddAttributeTable(builder.CreateTable());
        }
    }
    

    Visual Studio workflow designer will look for a dll ending with .Design.dll and, it it finds it, will execute IRegisterMetadata.Register() where you're attaching designers to activities.