Versioning Strategy for BizTalk Assemblies


I spent a bit of time today reviewing some best practices for assembly version in BizTalk applications, and wanted to also elicit community feedback.

One of the first things that a new BizTalk developer is told when building up a BizTalk solution is to not cram all the various artifacts into a single .NET project.  Often that developer will be told to put schemas in one project, maps in another, pipelines in another, and finally orchestrations in an isolated project.  I’ve become less of a fan of this rigid structure.  But first, let’s see how I’d do an upgrade of a solution configured this way.

I’m starting with a simple project, containing a single schema file.  The message looks like this:

I built and deployed this project and constructed a simple “receive location” and “send port” where the send port had a subscription/filter on BTS.MessageType.  I tested it, and everything travels through just fine.

Then I built a simple orchestration that makes a decision and writes to the event log.  It looks like this:

I referenced the schema project, built, deployed and tested the orchestration successfully.  The next step was to create a new version of the schema.  So, I added a “Status” node, and then changed the .NET Assembly Version.

I then rebuilt and deployed the schema project.  Now given that you’ve constantly been told that namespace#root has to be unique, the screenshot below may worry you. 

If you want to read more about how pipelines resolve schemas, read here.  So you may expect that I would get a “ambiguous reference” sort of error when I try and submit the inbound message now.  However, when I drop the file, the orchestration still picks it up, processes it and continues on its merry way.  But, what happens if I “stop” the orchestration so that I can see the message in flight, and investigate the SchemaStrongName property assigned by the pipeline?  What you’d see is this:

 

Surprise.  The schema resolved to the most recent version, and THIS is the one yanked in by the orchestration.  This surprised me a bit.  I would have expected the send port containing the BTS.MessageType filter to yank the most recent version of the schema since it only cared about “type”, but I had thought the orchestration would only grab the version it explicitly referenced.  Now if I try and remove the “1.0” schema assembly via the Admin Console, I get an error stating that the orchestration is referencing it.

So to get rid of the “1.0” schema project, I’d have to reversion the Orchestrations project with an updated build.  Then after gracefully transitioning to the new “1.1” orchestration, I could safely remove legacy assemblies. 

Now, if I used a custom receive pipeline, THEN it seems I can dictate the schema version the orchestration consumes (old schema or new schema).  I tested this by putting a receive pipeline (with XML Disassembler and Validator components) in the project with the schema.  I deployed that (version 1.0 again).  Then, I upped the version to “1.1” and built and deployed.  So, now I have schema/pipeline projects for “1.0” and “1.1” and an orchestration project still built with “1.0”.

By switching the pipeline, the orchestration would grab specific versions of the schema.  For instance, if I dropped a “1.0” message (no “Status” field) when the “1.0” pipeline was selected, everything ran fine.  If I dropped a “1.1” message with the “1.0” pipeline still in place, I got a suspended message.  Same situation when I flipped to the “1.1” pipeline.  The orchestration consumed either the “1.0” OR “1.1” message.

So, any conclusions here?  Changing .NET Assembly Version has broad impact, regardless of how you’ve factored your projects.  One recommendation I’ve seen is to only change the Assembly File Version so that you still have an incremented build number, but the core .NET version stays the same (allowing for lower impact changes).  However, that could get dicey if you are truly introducing breaking changes.  You’ll also see recommendations to version schemas by changing the namespace#root combination (e.g. changing the namespace to http://Microsoft.Project.BizTalkStuff.v1).  Of course then you HAVE to change all the dependent artifacts (maps, pipelines, orchestrations) because you’ve made a core modification.

This leads me to a solution structure that is less segmented by artifact type, but more by artifact relevance.  That is, group related artifacts in the same project.  You still may have a “base schemas” project, but it’s also ok to have a subsequent project that contains a few schemas, maps and orchestrations.  Try and group the items that will change and version together.  Now if I have to version the schema, I can fairly naturally version the sibling artifacts and deploy fewer assemblies.

So I ask you: any other versioning strategies that you prefer when you want to lessen the impact of production modifications?  How do you like organizing your solution structure?  If you only have to make a slight change, how do you prevent the rebuild of every dependent project?

Technorati Tags:

Comments (8)

  1. Jon Flanders says:

    Richard – I recommend to people only to version if you plan to run two assemblies side-by-side.  Otherwise I follow the rules in this blog post – http://www.masteringbiztalk.com/blogs/jon/PermaLink,guid,628aecb9-4eaa-4044-88c9-92cb53f81bdf.aspx

  2. Great chart.  I’m going to cut it out and put in under my pillow tonight.  It was actually one of your newsgroup posts from a while back that made me start thinking of this again!

  3. Jeff Lynch says:

    Richard,

    I agree with Jon in principle but still like to create a BizTalk (VS2005) solution made up of various (VS2005) projects for each BTS2006 "application". Each solution contains one or more projects including a "shared" project which is referenced by other projects. All projects in the solution are versioned and if one changes, then they all change. Since I usually deploy at the BTS2006 "Application" level using a complete msi and binding file, this works great, especially if I need to deploy side-by-side with a previous version. This also spares me the extra work of having to touch any custom pipelines just because of a schema change for example.

  4. brad says:

    I used to be very rigid about structure too, but discovered that life was just easier if I followed a simple rule …  If a "thing" is shared by more than one "related thing", then it gets its own assembly, otherwise one big project.  

    Example … schemas shared between more than one (group of) orchestration assemblies get split out.

    Conversely, schemas used by a single pipeline that feeds a single orchestration get grouped together.

  5. brad says:

    BTW, that chart is my friend too 🙂  I use it all the time.

  6. Here is a great post on how to organize your BizTalk projects and how to manage and version BTS assemblies.

  7. Chris Romp says:

    I’ve pinned that chart up at my desk.  Thanks!

    Another note regarding how BizTalk handles multiple versions: If you make a change to the major or minor version numbers, the assembly is identified as being different but supports side-by-side deployment (such as your example above — 1.0 to 1.1).

    If you change the revision number, the change is considered to be compatible with the previous version, but backward compatibility is not guaranteed.

    If you change the build number, it’s considered an engineering/bug fix and requires the previous version to be removed.

    Major.Minor.Revision.Build

    Source: Microsoft Course Manual 2934A, Module 3, Page 11.

  8. Chris Romp says:

    Brad: That’s sort of the method I’ve started to adopt as well.  It’s made management much easier!  =)