Simple Workflow Designer with Silverlight and MEF


Introducing simple workflow designer

I’m excited to announce another project from my collection went public today. This time it is a demo POC (proof of concept) implementation for a simple workflow designer written in Silverlight 4 and MEF.

01.slwfdesigner

The project contains the following features that may be interesting for review:

  • Design surface with drag and drop (MVC)
  • Toolbox with automatic runtime discovery of items (MVVM)
  • Drawing connections, live update of connections during drag and drop
  • Separate model layer with custom serialization support (functions, activities, workflows)
  • Separate presentation layer (visual elements for activities), styling and templating nodes
  • Runtime discovery of models and corresponding node views (decoupled layers)
  • Simple rules (i.e. “Output ” node may have only 1 incoming connection)

There are two modes supported out of box – Design and Source views.

Design view

This mode showcases the process of visual modeling. The process is divided into two separated areas – Toolbox and Design Surface.

02.slwfdesigner-designview

Toolbox hosts all items exported and discovered at runtime by means of MEF. Default set of activities resides in a separate “WorkflowDesigner.Activities.dll” assembly and can be easily replaced or extended. There’s also an additional “WorkflowDesigner.Sdk.dll” assembly that is mean to be shared across 3rd party libraries and aids in creating custom activity libraries.

You can add activities to the surface by double-clicking the corresponding item in the toolbox. For the sake of simplicity there is no drag and drop support for the toolbox but it can be easily introduced. The quickest way may be reusing Telerik’s drag and drop manager with fancy visual cues, but this is out of scope of this article.

Design surface is based on MVC pattern and showcases basic set of functions like: drag and drop of activities across the surface, drawing connection lines, removing nodes or connections, clearing entire surface. Every visual node is mapped to underlying model (activity) at runtime. That means that both activity and it’s visual representation are completely decoupled and any of the parts can be easily tuned or extended.

For demonstration purposes default activities emulate the behavior of OData- or SQL-based entities with simple UI editors, entire project emulates the process of creating a workflow that deals with data aggregation.

08.slwfdesigner-activity

UI dialogs are not bound to any particular business logic except assigning corresponding property values of the model entity. However this may be a good start building user experiences based on your real-life scenarios.

09.slwfdesigner-dialog3

06.slwfdesigner-dialog1

Source view

In addition the Source view feature is supported. It allows you switching to the XML representation of the workflow at any time during design process. Serialization is completely custom and was kept as simple as possible in order to be replaceable or customized. Based on your real-life scenarios the resulting XML can travel to server side and can be turned into object graph without UI dependencies, etc.

03.slwfdesigner-sourceview

Project structure

I will be giving only brief overview of the project structure in this article. Most of the code is split into 2 areas and resides in 2 different class libraries: “WorkflowDesigner.Sdk” and “WorkflowDesigner.Activities“:

04.slwfdesigner-activities

05.slwfdesigner-sdk

As soon as you figure out the process of creation of new activities you most probably may need only “WorkflowDesigner.Sdk” assembly that contains all core and shared functionality.

Source code

You can grab the source code at my GitHub repository.

Advertisements

Masonry Extensibility. Part 1.


This is a second post in a series of articles about Masonry starter kit. Please refer to this article in order to get more information about Masonry:

Announcing Masonry public preview

Masonry starter kit was designed with extensibility in mind from the very beginning. There are several out-of-box blocks that greatly reduce learning curve and efforts required to extend main navigation elements like sidebar and header bar, provide custom content and routing, integrate into help or search system or messaging pipeline.

Masonry is also shipped with a project template for Visual Studio 2012 that turns the process of extension library creation into a several mouse-click procedure.

Part 1 of this article will give a high-level overview of supported extensibility features as well as developer tools shipped with version 1.0

Part 2 will dwell on technical details of extension discovery, processing and mapping of dynamic/static content and UI composition.

Extensions in Masonry are based on Areas that are compiled into a single-assembly libraries and deployed to Masonry-based web application by means of xcopy. For more details on Areas in ASP.NET MVC please refer to the following articles:

Walkthrough: Organizing an ASP.NET MVC Application using Areas

ASP.NET MVC Areas – A Better Way to Structure The Application

Using Areas in ASP.NET MVC Application

Every Masonry extension depends on the following assemblies:

  • Masonry.Core.dll (required)contains low-level infrastructure required by Masonry and 3rd party extensions in order to function.
  • Masonry.Extensibility.dll (required)contains shared blocks that may be used by all or any 3rd party extension. For the moment of writing this article it consists mainly of UI-relacted contracts.
  • Masonry.Resources.dll (optional)contains default localized content that may be reused within extensions

Masonry does not require extra efforts in order to enable extensibility support for a web application, referencing “Masonry.Core” is usually enough to automatically enable underlying infrastructure.

There are two different modes supported by Masonry out-of-box: automatic (or convention-based) and controlled (or configuration-based) extension discovery.

Automatic extension discovery

This is the default mode and requires zero coding efforts besides referencing “Masonry.Core” assembly from within your Masonry-based web application.

Prior to web application startup the following workflow is executed automatically:

  • Underlying extensibility engine is initialized and started
  • All assemblies are discovered by “*.Extension.dll” mask and loaded
  • Custom ASP.NET MVC view and content providers (Masonry-specific) are initialized and wired with the extension libraries if loaded with previous step

With automatic discovery mode every 3rd party extension library must follow the following predefined conventions in order to allow resulting assembly to be discovered and loaded:

  • Extension assembly file name should end with “.Extension.dll
  • Default root namespace for the extension assembly should not end with “Extension” word

The process of configuring assembly file name and namespace for a new extension project is pretty simple. For example in order to configure a “Dummy” extension developer may need performing the following steps:

  • Create a .NET class library project named “Dummy” and navigate to project properties pane
  • Ensure “Default namespace” property is set to “Dummy”
  • Change “Assembly name” property from “Dummy” to “Dummy.Extension”

02.project-properties

Note: steps above can be omitted when using “Masonry Extension” project template for Visual Studio 2012 shipped with Masonry kit out-of-box. More details regarding project template will be given further in this article.

Controlled extension discovery

Due to security, performance, additional level of extension management and review, or any other reasons it is possible switching off automatic discovery for 3rd party extensions and defining them explicitly within configuration file (web.config) instead.

The following picture demonstrates registration of “Dummy” widget within configuration file:

01.webconfig

In this case the following workflow will be executed prior to web application startup:

  • Underlying extensibility engine is initialized and started
  • All assemblies from configuration file are discovered and loaded
  • Custom ASP.NET MVC view and content providers (Masonry-specific) are initialized and wired with the extension libraries loaded during previous step

The are no file and namespace naming conventions for configuration-based mode (as it is possible defining corresponding values within configuration file as well).

Extension project template

In order to greatly simplify development process and reduce amount of efforts and time needed to create and configure a new extension library Masonry is shipped with a special project template for Visual Studio 2012.

03.vstemplate

Important note: for version 1.0 the resulting project should reside within “Extensions” subfolder of the project like displayed on the picture. This is required in order to automate configuration of assembly references and Nuget packages for a newly created project.

Project template handles and automates development process by executing the following operations:

  • Creates new class library within “Extensions” subfolder
  • Configures all Masonry-related assembly references, wires project with required and/or optional Nuget packages
  • Enables Razor support for newly created project (code highlighting, intellisense, compilation, etc.)
  • Creates initial file structure that conforms to common ASP.NET MVC Areas design
  • Generates “Area Registration” settings for the given project including default route registration
  • Generates set of files that address basic extensibility scenarios, for example sidebar and header bar extensions, grouping, default “main content” and “about” pages, etc.
  • All generated files and automated settings take into account name of project

So upon creating a new project with this template you get a working Masonry Extension library that is ready to be instantly compiled and deployed to main web application.

By default Masonry also provides and embedded demo extension called “Dummy” that reuses most of the extensibility features:

05.extension-structure-expanded

The file structure of the project when using Masonry Extension project template will be nearly the same except the name of the area registration class, all code namespaces and all UI labels/names will be reflecting the name of the project you have defined at the creation stage. This means that multiple extensions created from the same template won’t conflict.

06.custom-extension

Here’s for example the content of the Area Registration file that was automatically generated for the “MyExtension1” project:

07.custom-arearegistration

And image below provides a quick example on a sidebar extension element generated automatically and aligned with your project name and settings:

08.custom-sidebar-integration

Needless to say that resulting project can be tuned in any way. Visual Studio template just takes care of the most frequent, repetitive and so time-consuming tasks.

Compiling and deploying extensions

Every class library created with “Masonry Extension” project template can be instantly compiled and deployed to a Masonry-based web application without any modifications.

As a result of successful compilation you will be getting a single assembly file with all the features and content required by extension.

Important note: all non-C# files related to ASP.NET MVC (i.e. “.cshtml” files) and static content should be marked as “embedded resources” in order to be included into resulting assembly and processed by Masonry at run time. It is possible including images, JavaScript, CSS, etc. files as embedded resources as well. Masonry will ensure those files are mapped properly during execution and behave as common MVC views or static/script files.

Besides changing build action to “Embedded Resource” developers need performing no actions. Picture below demonstrates the default set of files delivered by Masonry Extension project template as embedded resources:

11.extension-resources

Deploying compiled extensions has no special requirements or prerequisites. Resulting “.dll” file can be copied into the binaries folder of the target Masonry-based web application. Optionally you can drop debugging information (.pdb files) to enable debugging of deployed extensions and stepping through the code:

09.extension-binaries

Note: when using “controlled discovery mode” you may need defining a new configuration entry upon deploying your extension to the target web application.

Upon execution and extension discovery Masonry will automatically populate sidebar, header bar and other extensible UI areas with corresponding elements. Every action (link) will point to custom extension-provided content.

10.extensions-ui

This is the end of basic overview of extensibility in Masonry. In the second part I will be giving more information about areas that support extensibility in Masonry, classes and contracts that may be utilized when writing custom extensions, technical details on embedded resources and the process of mapping them at run time, and a lot more…