On the very first BizTalk project I worked on, refactoring was a really bad word that almost brought our Gantt chart to its knees. As with many agile projects, evolving requirements required changes to schemas, these changes often being major structural changes which broke all the maps they were being used in. Recovering from these changes could take ages with complex maps, and sometimes required developers to spin up a second PC with the old version of the map on display so they could re-implement the logic with the new structure.
Refactoring will never go away. It is a part of nearly every project to some extent or the other, however there any smarter ways to fix up your maps rather than starting from scratch. Following the guidelines I describe in this series of blog posts could help lower the cost of refactoring in certain cases (I’m not going to promise you the world, refactoring is hard), thus allowing for projects to be delivered sooner and reducing the need for developers to compromise the quality of their deliverables as much as they might otherwise have to for the sake of meeting deadlines.
The one disclaimer I’ll make which applies to the rest of these posts is that you should always make a backup of your map before editing it outside of the designer. I would not recommend manually editing any BizTalk artifacts except for schemas and maps, and even then successfully opening the artifact in its relevant designer should be considered the success criteria; if the designer won’t load the component successfully or displays the below error then you should consider your change to be a throwaway.
All the below guidelines will focus on the below map, which is of course a very simple example.
Refactoring for changes to target namespaces in schemas
Unless you’ve overridden the map designers default setting, making changes to the target namespace of a schema will have no effect on a map. This is because maps do not take the namespaces of schema nodes into account by default. Inspecting the above map in an XML view makes this very apparent when you look at the XPath statements that make up the map.
If you click on an empty space in the map design surface and then look in the properties window you will notice a property called “Ignore Namespaces for Links” which is set to true by default. If you set it to false (there are a few uncommon scenarios in which you might want to do this, don’t do it unless you have a good reason to) and inspect the map in XML view you’ll notice that the XPath statements now reference the node namespaces as well.
In the above scenario, simply searching for and replacing the old target namespace with the new target namespace would be all the refactoring that would be necessary to allow this map to continue working if the “Ignore namespace for links” property were set to false. I strongly suggest that if you have “Ignore namespaces for links” set to false and you are planning on changing your schema’s element form from qualified to unqualified or vice versa, that you switch the “Ignore namespace for links” property back to true, make your change, and then set the property back to false as this will help you avoid a lot of reconciling of namespaces.
Refactoring for changes to file names, moving between project, and changes to .NET namespaces/type names
Here’s the first piece of good new. If you change your schemas files names it won’t make a bit of a difference to the map. Neither will moving the schema file from one project to another (assuming you don’t change its .NET namespace/type and that the map project has a reference to the project the schema has been moved to), even if the projects are signed with different strong named keys. This is because schemas are referred to by maps using their fully qualified .NET types rather than by a relative file location. This is very apparent in the highlighted section of the below screenshot.
Now how about if you actually adjust the .NET namespace or the type name of one or both of the schemas (this assumes there are no changes to the root node name or any other elements in your schemas)? All you have to do is open the map file in an XML view and adjust the sections highlighted above so that they reference your new fully qualified .NET type names. This should get your map back in action in no time.
What can you look forward to in future installments of this blog series?
- Catering for changes to root node or other record names in one of your schemas
- Catering for changes to element names in one of your schemas
- Catering for changes to the structure of your schema (ie. moving elements into a record that didn’t previously exist etc…)
- Catering for changes to method names / assembly names / public key token of external assemblies referred to in scripting functoids
Please let me know if there are other scenarios you might like me to cover.