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…

Announcing Masonry public preview


Today I’m happy to announce the public availability of my new project “Masonry”. Please note that this post is a high-level overview of the project and its major features. For the sake of simplicity technical details are omitted. Developer-oriented articles will be published separately.

Introduction

Social networks and corresponding UI/UX gains more and more attention. Even big enterprise players are looking forward to embedding social and gamification features into their products these days. Most of the projects I’ve been involved with during this year had requirements for lightweight “socialization” of common business workflows, i.e. chats, timelines and data aggregation, comment systems, following/unfollowing, user profiles, etc. Most of the project prototyping I’ve observed or was part of during the year assumed Twitter/Facebook-like user experiences besides mandatory functionality requirements.

Masonry was born as an ASP.NET MVC4 starter kit (or template) to greatly reduce learning curve, time and development efforts required to start prototyping and building social-enabled web applications, or integrating social-enabled features into existing applications. It provides most common building blocks and allows startup or research teams concentrating on main application functionality rather than building social features from scratch.

Home Page

Overview

Masonry is not a static template. Many frequently required and expected features are still being researched, analyzed and included into the roadmap. You should expect frequent updates that bring new blocks in the future.

The major set of features shipped with initial beta is as follows:

  • Account registration with email confirmation/validation and reCaptcha support
  • Account settings and password management
  • Timeline and user posts (status updates)
  • Public profiles, following/unfollowing other users
  • Personal feeds and “twitterization” of content (account links, hash tags, etc.)
  • Comment system
  • Mentions and People hubs
  • Wiki-based help system with Markdown support
  • Extensibility support (single-assembly modules built with ASP.NET MVC4 template and deployed with xcopy)

There’s also a supplementary content to aid development:

  • Default demo database to get started instantly (SQL LocalDb)
  • SQL schema scripts to setup a new database
  • Visual Studio 2012 project template for creating custom extensions/modules with less efforts

Account Registration

Account management is built on to of SimpleMembership provider by MS used in most of the WebMatrix projects these days. That allows having more flexible membership scenarios (i.e. support for external OAuth authentication models, Facebook/Twitter/LinkedIn integration without much efforts) and provides greatly refined SQL database schema compared to popular ASP.NET SQL Membership provider.

Registration form prevents cross-site request forgery (CSRF) out of box by utilizing ASP.NET MVC’s AntiForgeryToken helpers.

Google reCaptcha is also preconfigured by default

Account Registration

In addition Masonry supports account validation and email validation. This feature when opted in through configuration allows automatically generating confirmation emails with links to confirm and enable newly created account.

Signing in

Similar to Registration form the LogOn one prevents cross-site request forgery (CSRF) attacks by default. All redirect URL links (used to redirect back to the requested content that requires authentication) are verified to be valid local addresses rather than external links.

Sign In

Timeline

All authenticated users are automatically redirected to the Timeline. Similar to Twitter it is a long stream showing all Posts from those you have chosen to follow, or your own posts with user comments. There are no paging controls on the Timeline, similar to Facebook new content is downloaded smoothly while you scroll down the page.

Timeline

All content is “twitterized” by default – all user account tags are turned into user profile links and point to Personal Feeds (see below), all hash tags are wrapped with hyperlinks redirecting to internal Search controller upon click. In addition all hash tags are enumerated in a separate area below the main post content.

There are at least 2 easy ways to post new content (i.e. status update) in Masonry:

  • Inline editor box at the bottom of the Timeline
  • “New Post” button on the header bar and available on any page

Image below demonstrates a dialog that appears when user presses “new post” button:

Status Update

Personal Feeds

Masonry provides support for personal feeds – streams showing public posts by a specific user. There are several ways quickly accessing personal feed:

  • User account name within the post header
  • User account tag within the post or comment content
  • Public profile dialog that pops up upon clicking user avatar
  • People or Mentions hub

Upon navigation the sidebar control will automatically reflect the account opened:

Personal Feed

Public Profile Popups

Masonry automatically wraps all user avatars with profile popups that allow following/unfollowing particular user, navigating to a personal feed or People hub to see followings/followers.

Profile Popup

Mentions

Similar to Twitter Mentions Masonry provides support for streaming posts that “mention” current user – i.e. any post that has an account tag in the content. All Timeline features like profile popups, comments, personal feed navigation are automatically applied to Mentions stream as well.

Mentions

People Hub

To simplify intranet/corporate scenarios Masonry provides a special feature “People Hub” that allows newly registered users discovering already existing members (to follow, view personal feeds, etc.). People hub lists existing uses with basic public information (see Account Settings section below) and main statistics like number of posts, followers or users being followed by a particular user. It is possible following/unfollowing users directly from the People hub:

People Hub

Note: it may be possible wiring People hub with additional logic and business rules, like showing/filtering users by department, etc.

Account Settings

Users can access their account and profile settings from the header bar. Besides account editing Settings drop down menu provides access to Help system, About information and allows signing out as shown on the picture below:

Settings

There are no mandatory fields within account settings section. All public fields are optional: photo, display name, location, website and bio. If current browser supports HTML5 File API user will be able to preview changes to the picture live without uploading any data to server.

Account Settings

Both “Account settings” and “Change password” forms provide lightweight unobtrusive alerts to indicate update results.

Change Password

Comment system

For extensibility and flexibility purposes Comment system in Masonry is separated from status updates (posts). To avoid user distraction comment areas are collapsed by default:

Generic Post

Moreover comments are loaded asynchronously upon expanding “Comments” area. That reduces initial page memory footprint and speeds up main content loading.

Post Comments

The author of the post has possibility removing posts with corresponding comments:

Removing Posts

Similar to Facebook Masonry supports displaying posts in separate pages. Every post that has more than 10 comments is automatically opened in a separate view.

Help System, Markdown Support

Help system is a separate block within Masonry that provides Wiki-like experience and powered by Markdown syntax.

Help System with Markdown

Underlying Help Controller maps physical “.md” files automatically, it is possible updating Markdown content with a running application:

Help Content

Markdown syntax

Extensibility and Modules

Masonry utilizes Managed Extensibility Framework (MEF) and ASP.NET MVC Areas to provide rich extensibility support. External extensions are discovered and loaded automatically with zero code configuration and prerequisites within main application. All extensions are represented by a single-file assemblies containing a fully-fledged ASP.NET MVC4 pieces together with static content, styleshees and javascript files.

Upon new extension library discovery Masonry automatically augments UI with additional entities taken from the corresponding plugin:

Extensions

Every custom extension can provide extra elements for header bar (with grouping support), sidebar, may provide user with additional content. With Masonry it becomes extremely easy extending standard UI and functionality.

Dummy Extension

In order to greatly simplify development process Masonry provides a special “Masonry Extension” project template that can be used with Visual Studio 2012. This project template takes care of project structure generation, enables Razor compilation and syntax highlighting for the generated class library project and contains all extensibility/routing settings automatically preconfigured.

Note: there will be a separate article that dives deep into Masonry extensibility, tooling and plugin development. 

That’s pretty it. Feel free to grab the code, play with it, request features that are important, file issues… everything is in the GitHub repository.

Thanks for following.

I’m back to blogging


After a long pause I’m finally back to blogging. This year was a very productive one, I’ve been involved in a series of awesome R&D projects related to Silverlight, ASP.NET MVC, Mono, etc. Lots of material to be turned into useful articles.

During this week there will be an additional announcement for the next big thing from my side – Masonry. That is a starter kit for social-enabled extensible MVC4 applications that enters public preview and going to land into my GitHub repository soon.

More information and posts are on the way.

Thanks for following me.

IL.View October 2011 Features.


October 2011 was a very busy month for IL.View in terms of new features  introduced.

The major features that are worth mentioning in this recap is as following:

  • Automatic updates for OOB (out-of-browser) scenario
  • Rich browsing for Silverlight packages (.xap files)
  • Platform identifiers for assemblies
  • Version numbers for assembly references
  • Content preview for some file types (xml/xaml/ClientConfig/jpg/png)
  • Displaying and expanding embedded resource assemblies (for Silverlight assemblies only) by pressing Space bar
  • Preview of embedded resources (xml/xaml/ClientConfig/jpg/png) by pressing Space bar
  • User-defined reference paths for automatic assembly resolution (similar to Visual Studio “reference paths” feature)
  • Lot of stabilization and improvements for underlying infrastructures
  • New assembly versioning schema based on “YYYY.MM.DD.{Build}” format

Automatic Updates

Live preview builds that are continuously  pushed to the project page got support for automatic updates. Users that are using the full-trust OOB (out-of-browser) scenario will get the application up-to-date automatically upon every launch.

Browsing Silverlight Packages

IL.View now provides rich capabilities for browsing Silverlight packages (“.xap” files). Users are now able to drag and drop “.xap” package directly onto the application surface and view package contents. Package browsing includes full support for content and assembly navigation in the same way it is done for a regular assembly.
Silverlight Package Browsing

Platform identifiers for assemblies

As application is moving forward having a single list of assemblies within the browser the platform identifiers were added to assembly names. Silverlight assemblies will be marked as “(SL)” while .NET assemblies will be marked as “.NET”. Later on identifiers will be extended to display the actual version of the corresponding framework.

Platform Identifiers

Version numbers for assembly references

To improve dependency analysis process the application provides version numbers for assembly references within the reference title. That allows to avoid unnecessary decompilation or assembly resolution calls when it is only the version of reference the user is interested in.

Version numbers for assembly references

Content Preview

It is now possible to view the content of the files that are frequently added to the “.xap” files. IL.View provides support to show xml-based files (xml, xaml, ClientConfig) with syntax colouring:

Content Preview of xml-based files

 It is also possible to preview the content of image files in the formats supported by Silverlight (.png and .jpg). Images are displayed in real sizes.
Content preview for image files

Browsing embedded resource assemblies

October version of IL.View brings out support for embedded resource assemblies navigation. This feature is however limited to only Silverlight assemblies. A new node called “Resources” will appear next to every main module of the assembly. Resource assemblies can be expanded like regular assemblies and their xml/image-based content can be previewed by pressing a Space bar on the selected item.

Browsing embedded resources

 Reference Paths

Application now provides a way to define common reference paths that should be used for assembly lookup during decompilation and reference resolution. There will be a new options panel called “Reference Paths” within the “Settings” page. The user is able to add or remove a path to any directory containing .NET or Silverlight assemblies that needs to be checked during decompilation process. Every single reference path can be configured to use recursive search, meaning that the entire folder tree (including all sub-folders) is going to be inspected. However recursive search is a time consuming event and users discouraged to use it against deep nested folders.

Every time an external assembly is found the path to the file is cached. This gives much better performance during next sessions.

Reference Paths

This feature is however limited to full-trust mode running on Windows machines. “Reference Paths” section won’t be displayed when running IL.View on non-Windows computers (i.e. MacOs).

New Versioning Schema

New assembly versioning schema was applied based on “YYYY.MM.DD.{Build}” format. The version number can now be checked at the “About” page:

Versioning Schema

Besides new features there was a lot of stabilization work performed.

More and more features are being registered within the issue tracking system.

IL.View: .NET Reflector OSS Alternative. In Silverlight!


Today I would like to announce a new project I’ve been working on to contribute to the .NET community.

The project is called “IL.View” and it is a .NET Reflector alternative made in Silverlight 4 as an Out-of-Browser Silverlight Application. “IL.View” sources will be published under the MIT (X11) license to the following GitHub repository in the next couple of hours. As soon as Google fixes “If-Modified-Since” bug the online version of “IL.View” will hopefully become immediately available with “Google App Engine”.

image

Background

I’ve started planning this project approximately 2 weeks before infamous Red Gate announcement that “.NET Reflector” goes commercial way and so approximately 2 weeks before an awesome OSS alternative appeared: ILSpy. So “IL.View” background is not an emotional move and is not going to be abandoned with the ILSpy arrival (like Monoflector for instance).

I am a Silverlight developer and my team does a lot of really crazy stuff related to Silverlight, Azure, REST and OData. During the “demo” and “testing” periods we have to deal with publishing a lot – different versions of Windows Servers, various IIS versions, different .NET frameworks at server sides, multiple remote desktops and issue addressing, etc.

One of the issues I’ve experienced in the past (and according to Google I’m not alone with that) is the process of brining .NET Reflector to server side in order to have a quick look at my assemblies. You should be able to download it from somewhere for every server (of course if you have rights to download and install anything), you need to have a proper .NET Framework installed on server side (Reflector itself requires .NET 3.5 or later to be present), etc.

Actually the very same problem may be valid for ILSpy as well. If it is compiled for .NET 4.0 framework you cannot use it at server having .NET 3.x only. So the idea of having a Silverlight version hosted in the company intranet (or in the cloud) was very appealing as it could save time and reduce efforts.

Another feature I was dreaming of is “Remote Assembly Cache” or the possibility to decompile .NET assembly without binding to local machine – even without having any .NET framework installed at all. For example having a remote web service (pure REST, OData, whatever) to resolve .NET dependencies upon being needed. This could open a brand new set of scenarios for me. Having no bindings to local machine could for example allow Mac users to disassemble .NET assemblies easily and drilling down to “mscorlib” or any other part of .NET framework without difficulties (this feature is in progress for “IL.VIew” and will be available later on).

Third major feature I was trying to address is extensibility. NET Reflector always deserved better extensibility support and more complex addins from both code and presentation points of view.

Overview

As I’ve mentioned above “IL.View” is an OOB (Out-of-browser) Silverlight 4 application (Full Trust). It supports drag and drop for .NET assemblies from the desktop or Windows Explorer and provides a local cache of assemblies that were loaded (with the possibility extending the cache manually). “Assembly Browser” control supports “lazy loading” so you get disassembling process on demand. There’s a native “IL” formatting and “C#” one (in progress).

There are several ways “IL.View” can be deployed and used:

  • Online (cloud, web site)
  • On-premise (intranet)
  • Local installation
    Some features that are in progress will allow “IL.View” users to get maximum benefit of both cloud and on-premise deployments.

Mono.Cecil

“IL.View” is not using .NET Reflection. It is being build on the top of Silverlight port of “Mono.Cecil”. This is a tremendous project and I would like to thank Jb Evain for his work. Thanks to Cecil I got an opportunity dealing with both .NET and Silverlight assembly inspection within Silverlight runtime.

Despite the asynchronous nature of Silverlight the Cecil integration went well. “IL.View” provides its own dependency resolution facility that is capable of properly locking the UI and waiting for the user to perform actions:

SNAGHTML103147e

SNAGHTML14fc8c1

ICSharpCode Decompiler and NRefactory for Silverlight

The biggest challenge for me was “C#” output support. Not to reinvent a wheel I’ve decided to stick to ICSharpCode.Decompiler and ICSharpCode.NRefactory projects that are the part of ILSpy.  The only problem I came across is the absence of Silverlight ports for the mentioned projects. So I’ve took the challenge to port them to Silverlight myself. You can find the sources at my GitHub repository. First attempts were quite tricky, but thanks to the ILSpy team the original codebase becomes more and more “portable-friendly”.

As a result I have managed to provide C# output based on ILSpy libraries:

image

JetPack Theme

“IL.View” UI is based on the great “JetPack Theme”. However I had to provide a set of bugfixes for templates and styles in order to make some of the components look properly and behave as expected.

Notes

The project is still in its early stage but is going to evolve rapidly. There’s a huge backlog of features and roadmap will be announced later on. “IL.View” does not compete with ILSpy and I would love to contribute eventually to both .NET Reflector alternatives in the nearest future.

VS 2010 bug related to Silverlight 4.0 compilation


Some time ago I came across the problem of compiling Silverlight 4.0 with Visual Studio 2010 when using XmlnsDefinitionAttribute attribute. I have reported the problem to Microsoft but for the time of writing this post I haven’t yet received confirmation of the bug. However more and more people around me start to experience the very same problem with VS 2010 so I’ve decided to publish some details towards the problem as well as possible workarounds that can be used until the bug is confirmed and some sort of hotfix is available.

The problem is that under some specific circumstances Visual Studio 2010 will fail compiling Silverlight 4 assembly if it refers to any other assembly via xmlns mapping in the root of the XAML.

Here you can find a sample solution that addresses this problem: VSBuildBug.

Here’s the brief overview of the sample code:

1. Silverlight 4.0 assembly “SharedComponents” contains a User Control called “SharedControl”

2. The assembly “SharedComponents” maps one of its namespaces to an Uri (in my case it is “https://denisvuyka.wordpress.com/vsbugs”)

3. Silverlight application “VSBuildBug” references “SharedComponents” assembly

4. Application contains a “MainForm” that is declared my means of the namespace mapping: <shared:UserControl xmlns:shared=”https://denisvuyka.wordpress.com/vsbugs”…

When you open the solution attached with VS 2010 and try compiling it you will receive the following error:

The type or namespace ‘SharedControl’ could not be found (are you missing a using directive or an assembly reference?” (see the screenshot below)

clip_image002

However theoretically everything should compile without any problem. Some of the guys I’ve contacted towards this problem just gave up using xml namespace mappings thinking that the problem is in Silverlight itself but it’s wrong. This use case is absolutely correct and can be compiled.

The first workaround is calling “Build – Rebuild solution” several times in a row. At some stage you will receive “successful compilation” result and after that you will stop getting errors both for “Build” and “Rebuild”. However everything will be ok until the “Build – Clean solution” call or until you get a brand new version of the solution from the source control for example. Also different versions of Windows require different number of rebuild cycles. I didn’t bother figuring out the correct numbers, I can only confirm that on Windows 7 you may need about 3-4 “rebuild” calls while Windows XP may require 5+ “rebuild” calls.

After you made it compile you can reproduce the problem any time again. Just call “Build – Clean” solution and try “building” or “rebuilding” it again. The compilation problem will come back and you may need repeating the “rebuild” cycle one more time.

I’ve decided to go further with my investigation as I was wondering why TFS builds do not fail under the same conditions. I’ve ended up with a more reliable solution that I am using nowadays – msbuild tool.

If you unpack my solution once again and compile it from the VS command prompt using msbuild (just “msbuild VSBuildBug.sln”) you will never get an error. You won’t get errors calling “Build – Clean” solution and then using msbuild to build it as well.

So the second and most reliable solution is using msbuild tool to produce a solution. In case of avoiding full cleanups with “Build – Clean” solution developer may need calling msbuild only once getting a brand new version of codebase from TFS.

After finding a reliable workaround I’ve decided to go deeper into the details and see why auto-generated code is not compiling.

I’ve opened “MainPage.g.i.cs” with Visual Studio to get notifications when it is changed and to have an opportunity to see how it was changed. After a couple of experiments I’ve noticed that first two compilations (and code generations) does not produce the very same code behind actually.

Steps to reproduce:

Step 1. Open demo solution and call “Build – Clean solution”

Step 2. Call “Build – Rebuild”

You should see the same error I’ve described earlier:

clip_image002[4]

If you open the auto-generated “MainPage.g.i.cs” you should notice that “MainPage” inherits “SharedControl” but no references to external component library are present (neither within “using” clause nor type declaration). See the screenshot below:

clip_image002[6]

clip_image002[8]

I completely agree that this code should not compile even theoretically and Visual Studio gives me the correct output stating about missing references.

Step 3. Call “Build – Rebuild” for the second time.

You should get the very same compilation error again:

clip_image002[10]

However if you have “MainPage.g.i.cs” file opened in VS 2010 you will get a notification that its content was changed. Alternatively you can locate this file and open it manually.

After the second rebuild the type definition looks like the following:

clip_image002[12]

As you can see now VS generated another version of code behind that correctly references the “SharedControl” type. The namespace is provided and code should theoretically compile fine. But it does not.

Step 4. Call “Build – Rebuild” 3rd time

You should receive notification that compilation was successful (please don’t forget about my notes at the beginning that I am using Windows 7, it was noticed that Windows XP environments sometimes require more “rebuild” calls).

Third compilation does not produce a new code behind file and its content is equal to those produced during the Step 3.

I’m pretty sure VS is doing something wrong between steps 2–4. Two different code generation outputs for the same action that was just called twice seems to be very suspicious.

The only idea I have for the moment is that “MainPage.g.i.cs” was generated AFTER the rebuild procedure has finished. And the 3rd rebuild is just using the file generated during the 2nd pass. If that is true then it makes a perfect sense why 3rd pass was successful. And if I’m right then developers may potentially encounter even more serious problems in the future because there will be always a possibility testing the code that was built without exception but does not contain changes or bug fixes that needs to be verified by developer if you see what I mean.

The only thing I don’t understand for the moment is why VS 2010 produces compilation errors while msbuild works fine. I expected VS 2010 is using msbuild under the hood for building Silverlight but my investigation results make me think that there are two ways of building (please correct me if I’m wrong, I didn’t try reflecting VS to find an answer for this question) and the build procedure embedded into VS is definitely having issues.

 

Conslusion

I still think that xml namespace binding is a very important feature that needs to be reused as much as possible (see more details here: “Prefixes and Mappings for Silverlight Libraries”) at least because of the following benefits:

  • helps a lot with xaml/code generation scenarios;
  • helps a lot with component discovery (we all love intellisense);
  • reduces a variety of problems related to code refactorings and type namespace changes;

I’m pretty sure Microsoft will provide a hotfix as soon as this issue is confirmed but meanwhile you can use “msbuild” or “continuous rebuild” workarounds to keep using xml namespace mappings within your projects.

Any feedback is appreciated.