by Richard | Jul 5, 2007 | BizTalk Community Blogs via Syndication
>
> **Update 2012-03-28**
Unfortunately the images for this post was lost in upgrade of the blog.
>
>
This post shows how it’s possible to create your own .NET class and then use this within your orchestration (as a variable) to work with typed lists – something that unfortunately isn’t supported out of the box in BizTalk orchestrations. Below is the class used to create a typed list for System.String objects.
<span class="kwrd">using</span> System;
<span class="kwrd">using</span> System.Collections.Generic;
<span class="kwrd">using</span> System.Text;
<span class="kwrd">namespace</span> Sample.BizTalkCollections
{
[Serializable]
<span class="kwrd">public</span> <span class="kwrd">class</span> StringList
{
<span class="kwrd">private</span> List<<span class="kwrd">string</span>> _list = <span class="kwrd">new</span> List<<span class="kwrd">string</span>>();
<span class="kwrd">public</span> <span class="kwrd">void</span> Add(<span class="kwrd">string</span> item)
{
_list.Add(item);
}
<span class="kwrd">public</span> <span class="kwrd">int</span> Count()
{
<span class="kwrd">return</span> _list.Count;
}
<span class="kwrd">public</span> <span class="kwrd">bool</span> Remove(<span class="kwrd">string</span> item)
{
<span class="kwrd">return</span> _list.Remove(item);
}
<span class="kwrd">public</span> <span class="kwrd">void</span> RemoveAt(<span class="kwrd">int</span> index)
{
_list.RemoveAt(index);
}
<span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">string</span> ToString()
{
StringBuilder builder = <span class="kwrd">new</span> StringBuilder();
<span class="kwrd">foreach</span> (<span class="kwrd">string</span> item <span class="kwrd">in</span> _list)
{
builder.AppendLine(item);
}
<span class="kwrd">return</span> builder.ToString();
}
}
}
Notice that the class is serializable so BizTalk can serialize when dehydrating the orchestration to the database. We’ve also chosen not to extend the IList interface as we don’t want to expose all methods of that interface, but only the once we’ll really going use within our orchestrations.
This StringList class exists within the BizTalkCollections namespace where we have other classes for lists types with different datatypes (for example ObjectList, Int32List and so on). Below is a picture showing the structure of the Visual Studio project containing all the collections we current have implemented. This project and the BizTalk testproject is available for download here.
In the orchestration we then have set up a variable and type this to our StringList class within the Sample.BizTalkCollections namespace.
Also make sure the assembly with your collection class is installed in the GAC, otherwise you’ll end up with a FileNotFound exception saying
>
> Could not load file or assembly ‘Sample.BizTalkCollections, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7109528d5dbf986b’ or one of its dependencies. The system cannot find the file specified.
>
>
Then you can use the following code within your orchestration! Download the sample project and test it.
A really generic class
I’d really like for it be possible to create my own generic classes and then initialize these using something like the below.
genericList = Sample.BizTalkCollections.GenericList<System.String>();
However this isn’t possible as BizTalk orchestrations don’t seem to understand generic classes … If someone found a solution to this please let me/us know via the comments to this post.
by Richard | Jul 2, 2007 | BizTalk Community Blogs via Syndication
I’ve just found out that I get to go to TechEd in November! I haven’t been there before. I’ve been to a lot of conferences but not the Microsoft conference. Do I have to say that I’m looking forward to it?
If you’re going and feel like meeting up for a BizTalk lunch, dinner or whatever don’t hesitate to drop me an e-mail.
by Richard | Jun 4, 2007 | BizTalk Community Blogs via Syndication
Update 2007-07-05: The example project used in the post can be downloaded from here.
The operations dll (Micrsoft.BizTalk.Operations) is one of the new bits in BizTalk 2006 that at least I haven’t heard much about (most of you probably find in the C:Program FilesMicrosoft BizTalk Server 2006 folder). However it’s a library with a lot of useful functionality.
In this post I’ll focus on how it’s possible to use the library to get hold of message parts and message context from the BizTalk tracking database (usually called the BizTalkDTADb). If you’re unfamiliar with the architecture of the tracking in BizTalk this article is a good place to start.
What used to be the problem?
In BizTalk 2004 one soon got into problems when trying to read the message parts and the message context from the tracking database. The problem is that the the Xml is compressed (something that makes totally sence – Xml is a perfect candidate for compression). To my knowledge no one has found a good way to decompress the message context. There’s however a way to decompress the message parts (and only the parts) that Rob posted on in the BizTalk newsgroup. But this method doesn’t work on the compressed context of the same message that the parts belong to! One could assume that the same method could be used for both compression and decompression but I haven’t got it to work for the context of the message (read about my frustration here)
What’s wrong with WMI and MSBTS_TrackedMessageInstance?
So the option that was left to us before BizTalk 2006 for reading all the message parts as well as the message context was to use the MSBTS_TrackedMessageInstance WMI scrtipt and save everything down to file. The problem with this approach is that it’s slow and ugly! Say that we like to save a couple of thousand messages from the tracking database. When forced to save the messages to file we’ll end up with a slow and ugly solution where writing to file takes ages, then we have to read the content of the different files before cleaning up and deleting the files.
Micrsoft.BizTalk.Operations to the rescue
A quick view in Lutz Roeder’s Reflector shows us a couple of interesting methods in the operations dll. However I’ll only use the GetTrackedMessage method in this post.
I’ve written a tiny test application that uses the library to read the body part of the message (the meat of the message) and a couple of properties I’m interested in from the context of the message. It looks something like this. If your interested drop me an email and I’ll send it. The first screenshot below shows an example of reading the InterchangeID from the context of a tracked message.
This screenshot shows an example of reading the full body of a tracked message from the tracking database. Try doing this with less then 10 lines of code using the MSBTS_TrackedMessageInstance script!
There is really nothing to the application, reading a tracked message using the MessageID will return an object implementing IBaseMessage and we basically read the BodyPart property of – it really couldn’t be any easier.
<div><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">static</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">string</span><span style="color: #000000; "> GetMessageBodyByMessageID(</span><span style="color: #0000FF; ">string</span><span style="color: #000000; "> dbServer, </span><span style="color: #0000FF; ">string</span><span style="color: #000000; "> dbName, Guid messageID)
{
TrackingDatabase dta </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">new</span><span style="color: #000000; "> TrackingDatabase(dbServer, dbName);
BizTalkOperations operations </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">new</span><span style="color: #000000; "> BizTalkOperations();
IBaseMessage message </span><span style="color: #000000; ">=</span><span style="color: #000000; "> operations.GetTrackedMessage(messageID, dta);
</span><span style="color: #0000FF; ">string</span><span style="color: #000000; "> body </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">string</span><span style="color: #000000; ">.Empty;
</span><span style="color: #0000FF; ">using</span><span style="color: #000000; ">(StreamReader streamReader </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">new</span><span style="color: #000000; "> StreamReader(message.BodyPart.Data))
{
body </span><span style="color: #000000; ">=</span><span style="color: #000000; "> streamReader.ReadToEnd();
}
</span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> body;
} </span></div>
I’d be very interested in how people use the operations library both when it comes to read and use tracked messages, but also in other ways! Use the comments to tell me and other readers how you use it your solutions!
by Richard | May 14, 2007 | BizTalk Community Blogs via Syndication
Ever had a “use of unconstructed message” error message in your orchestrations? Then you know that messages has to be constructed before one can use them within orchestrations. Basically messages in orchestrations are created in ports or when executing a map in a construct shape. However there is also the possibility of creating messages in expression shapes using code. Matt Meleski does a great job explain the different approaches in his Constructing BizTalk 2004 XML Messages (In an Orchestration) – Choices blog post.
However there are some pitfalls when constructing messages from scratch within orchestration (a part from the fact that there really isn’t a clean way of doing it … Scott Colestock has some ideas in this post).
A common problem is XPathUpdateException. Say one has a mapping that looks like the one below where one node isn’t mapped. This will create a message without the ElementB element. This doesn’t have to be in a mapping, it could also happend when constructing a message using code in a expression shape. A common scenario is that we add code for constructing the bone structure of the XML message, then change the schema without updating the construct code. Ergo a message will be constructed without that element (could be both valid or invalid XML then depending on the Min Occurs value)!
[](../assets/2007/05/windowslivewriterxpa.setdistinguishedfieldwhileassigningv-ceb2complexmapping23.jpg)
When we then try to add a value to the element that hasn’t been created the exception will be thrown!
One way around when using a map is to make sure to have a default value on every element to force them be constructed. Adding the following to map will make it work.
It’s a one time mistake but it’s good to know what to look for when the XPathUpdateException in Microsoft.XLANGs.Core.XSDPart.SetDistinguishedField (if it’s a distinguished field that is) shows up in the event log.
by Richard | May 11, 2007 | BizTalk Community Blogs via Syndication
I’ve just finished reading a paper written by David Pallmann.pdf) (PDF) from Neudesic. Belive it or not (or even better check it out), it’s a short and understandable description of what an ESB is!
Neudesic sells a product called Cyclone which is something they call a ESB architecture and framework software and even if describing this product is the main purpose of the paper the first part deals with describing the basics of an ESB and try’s to “assemble a synthesis of popular ESB definitions”.
I’ve chosen a couple of parts of the paper that really appealed to me but I really recommend the full length version (only 8 pages!).
Defining the ESB
>
> * An ESB is a backbone for connecting and integrating an enterprise’s applications and services.
> * An ESB provides the necessary infrastructure to create a service oriented architecture.
> * An ESB is a convergence of EAI, MOM, and SOA concepts.
> * An ESB is based on open standards such as XML, SOAP, and WS-*.
> * An ESB provides intelligent routing, such as publish-subscribe, message brokering, and failover routing.
> * An ESB provides mediation, overcoming data, communication, and security differences between endpoints.
> * An ESB integrates with legacy systems using standardsbased adapters.
> * An ESB provides logical centralized management but is
physically decentralized.
> * An ESB is able to apply EAI concepts such as rules and
orchestrations.
> * An ESB is able to monitor and throttle activity as per a Service Level Agreement (SLA).
>
I never thought of an ESB as an convergence of EAI (Enterprise Application Integration), MOM (Message Oriented Middleware) and SOA (Service Oriented Architecture) concepts. But, ok, so what does the writer really mean by these concepts?
SOA makes loosely-coupled, decentralized solutions possible that are enterprise-ready and based on interoperable standards. EAI allows integration of any combination of systems, with sophisticated message brokering, message translation, business process orchestration, and rules engine processing. MOM provides intelligent routing such as publish-subscribe topical messaging and strong managerial controls over routing, auditing, activity monitoring, and throttling.
>
>
And why do we need a bus architecture on top of SOA, MOM and EAI?
Point-to-point architecture
works all right on a small scale, but its problems become
apparent when used at the enterprise level. If each system has to know the connection details of every other system, then each new system added increases the problem of configuration and management exponentially. This was the impetus that led us to hub-and-spoke architectures, which most EAI products use. This architecture was a vast improvement over point-to-point architectures, and each system needed to communicate with only the hub. In addition, the hub could provide excellent management features since it was a party to all communication. It only took time to reveal some shortcomings with the hub-and-spoke approach, and today it is often associated with concerns about scalability, single point of failure, and vendor lock-in.
>
> …
>
> Fortunately, there is a sound compromise to be found in the bus architecture, which provides the benefits of logical centralization but is physically decentralized. The bus architecture in earlier days was often used in message bus systems based on proprietary technologies, but an ESB implements this architecture using WS-* standards.
>
>
So using all three of them will make an ESB? Well, not really …
If combining disciplines was all there was to an ESB, we’d simply call it “consulting”. To properly leverage these disciplines they need to be combined in the right way through an architecture that lets their strengths shine and overcome their inherent weaknesses. Each discipline has some weak areas that the others help to resolve: SOA needs better enterprise manageability; EAI needs to become decentralized; MOM needs to get away from proprietary technologies. Combining these disciplines properly in an ESB overcomes these weaknesses.
>
>
I’d be very intreseted in comments of other artciles, papers and so on relating to the ESB concept!
by Richard | Apr 18, 2007 | BizTalk Community Blogs via Syndication
Recently I had to insert a record using a stored procedure and the SQL Adapter in BizTalk 2006. There are lots of examples on both how to insert records and how to select a number of record using this adapter. However I had problems finding how to insert a record and receiving the new id of the inserted row in return (the SCOPE_IDENTITY()). In my scenario I needed the id to insert into another database further down in the orchestration.
I ended up with a stored procedure looking like the below.
<div><span style="color: #0000FF; ">ALTER</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">PROCEDURE</span><span style="color: #000000; "> </span><span style="color: #FF0000; ">[</span><span style="color: #FF0000; ">dbo</span><span style="color: #FF0000; ">]</span><span style="color: #000000; ">.</span><span style="color: #FF0000; ">[</span><span style="color: #FF0000; ">TestInsertParty</span><span style="color: #FF0000; ">]</span><span style="color: #000000; ">
</span><span style="color: #008000; ">@partyName</span><span style="color: #000000; "> </span><span style="color: #000000; font-weight: bold; ">nchar</span><span style="color: #000000; ">(</span><span style="color: #800000; font-weight: bold; ">30</span><span style="color: #000000; ">) </span><span style="color: #808080; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">NULL</span><span style="color: #000000; ">
</span><span style="color: #0000FF; ">AS</span><span style="color: #000000; ">
</span><span style="color: #0000FF; ">BEGIN</span><span style="color: #000000; ">
</span><span style="color: #0000FF; ">SET</span><span style="color: #000000; "> NOCOUNT </span><span style="color: #0000FF; ">ON</span><span style="color: #000000; ">;
</span><span style="color: #0000FF; ">Insert</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">Into</span><span style="color: #000000; "> Party (</span><span style="color: #FF0000; ">[</span><span style="color: #FF0000; ">name</span><span style="color: #FF0000; ">]</span><span style="color: #000000; ">, chain_idx) </span><span style="color: #0000FF; ">Values</span><span style="color: #000000; ">(</span><span style="color: #008000; ">@partyName</span><span style="color: #000000; ">, </span><span style="color: #0000FF; ">NULL</span><span style="color: #000000; ">)
</span><span style="color: #0000FF; ">Select</span><span style="color: #000000; "> </span><span style="color: #FF00FF; ">Scope_Identity</span><span style="color: #000000; ">() </span><span style="color: #0000FF; ">As</span><span style="color: #000000; "> Id </span><span style="color: #0000FF; ">For</span><span style="color: #000000; "> Xml </span><span style="color: #000000; font-weight: bold; ">Raw</span><span style="color: #000000; "> (</span><span style="color: #FF0000; ">'</span><span style="color: #FF0000; ">Response</span><span style="color: #FF0000; ">'</span><span style="color: #000000; ">)
</span><span style="color: #0000FF; ">END</span></div>
The trick was to use the XML RAW Mode. This mode transforms the result set into a generic identifier as . It is however possible to provide a element name, as _. Basically this will insert the new value and return something like this from the stored procedure.
<div><span style="color: #0000FF; "><</span><span style="color: #800000; ">Response </span><span style="color: #FF0000; ">Id</span><span style="color: #0000FF; ">="1054"</span><span style="color: #FF0000; "> </span><span style="color: #0000FF; ">/></span></div>
After return via the send port the orchestration will receive something like the below.
<div><span style="color: #0000FF; "><</span><span style="color: #800000; ">TestInsertResponse </span><span style="color: #FF0000; ">xmlns</span><span style="color: #0000FF; ">="TestInsert"</span><span style="color: #0000FF; ">></span><span style="color: #000000; ">
</span><span style="color: #0000FF; "><</span><span style="color: #800000; ">Response </span><span style="color: #FF0000; ">Id</span><span style="color: #0000FF; ">="1054"</span><span style="color: #FF0000; "> </span><span style="color: #0000FF; ">/></span><span style="color: #000000; ">
</span><span style="color: #0000FF; "></</span><span style="color: #800000; ">TestInsertResponse</span><span style="color: #0000FF; ">></span></div>
The schema that I use to both handling the response and request against the SQL Adapter is shown below. First I set the type of the Id-attribute to xs:int but this gave me some problems when using the promoted value in the orchestration, everything worked fine when switching back to xs:string.
The same technique would be used for receiving a code from the stored procedure (say 1 for success and 0 for failure or whatever) and then to make a logical decision in the orchestration.
by Richard | Apr 5, 2007 | BizTalk Community Blogs via Syndication
Convoying is one of BizTalk’s real strengths but it has a lot of pitfalls (I’m talking performance, zombies etc). This article is really good at explaining the different patterns used for creating convoys. It also makes some deep dives into how the subscriptions are solved, why zombies are created and how to deal with them.
Even if you feel you understand the convoy patters from before the part about how BizTalk solves the subscriptions for correlations (the part called Basic Convoy Theory) is great.
Using sequential convoy to handle ordered delivery
A big selling point in BizTalk 2006 is it’s ability to handle Ordered Delivery. It’s important however to understand that this setting (on the Receive and Send port) only works in a pure messaging scenario (a scenario without orchestration, just passing messages between ports). To get order delivery in a scenario using orchestrations one has to use the sequential convoy pattern (basically forcing the orchestration to only one instance on one thread). This Webcast explains this in depth and also deals with some of the different problems that are related to the issue. Problems like performance of course, but also the requirement for receive adapter (on the send side all adapters support ordered delivery) for enabling ordered delivery (you’ll have to use MSMQ, MQSeries or specific scenarios of File, SOAP or HTTP).
Both convoying and ordered delivery are important concepts to understand in depth to be able to make the right decisions in a BizTalk 2006 solution.
by Richard | Mar 2, 2007 | BizTalk Community Blogs via Syndication
I’ll start trying to post a weekly sum up of BizTalk, .NET topics I’ve come across during the week. We’ll see how goes as I’m not the most constant blogger …
However I worked with mainly three things this week.
Error handling and General Exception
I’ve tested some ideas relating to an error handling pattern we like to implement in a one of our major integration projects. We’ve looked at how the new BizTalk 2006 Failed Message Routing fits in with our project. The idea is to have and Orchestration listening to the Error Message, log these and then put the failing message parts to file. We’ll then have a system that picks up the failed messages, launches them in an editor and makes it possible to resend the message after it’s been edited.
Problem arises when we get to handling exceptions in Orchestrations. Orchestrations doesn’t have the possible to use Failed Message Routing as ports does (I guess that ok, we might want handle different errors in different ways and so on.). However that means that we have to catch an error and create our own Error Message to submit to the message data box for further routing to the Orchestration handling errors (the one that logs and puts the message to file.) So far so good as long as we don’t get an General Exception! Usually when getting an General Exception, and we don’t catch it, the message gets suspended and we get a some error details giving us an idea of what went wrong. However as soon as one catches a General Exception we loose all information about the error … We’ve still haven’t found a good way of handling these errors. We just can’t afford loosing that error information!
General Exceptions are still a mystery to me. I guess that are there so BizTalk has a chance in catching exception that aren’t raised from .NET based code. But what kind of errors within an orchestration raises these kind of exceptions? I know a failure in a mapping does, what else? I’d really like this scenario to better documented. The error handling patter is based on a chapter in the Pro BizTalk 2006 book (which is a excellent book in my opinion – buy it!) but the General Exception and how to deal with it isn’t discussed there either. Any ideas, book, articles are highly appreciated!
Validation
One important thing to think of in a BizTalk solution is to not let anything either in or out that doesn’t validate (ok, there are exception to this, but generally speaking)! BizTalk has great built in support for this in the XML Validator Pipeline Component (you might also want to have a look at this code). However when working with this it’s important to understand what one is validating against and it suddenly even more important to understand every details in the schemas (external system owners usually like some technical explanation when your telling them that their messages don’t validate in your pipeline ;)). Things we run into this week is the elementFormDefault attribute. The following reading help me understanding what the attribute does:
Another thing we ran into was white space handling and the xml:space attribute. Apparently if one likes to have a node with a space in it BizTalk removes this if the element doesn’t have the xml:space attribute. so will come out as – sound familiar?
But if the schema doesn’t declare that the node will have a xml:space attribute the validation will fail! To get this working one has to get the schema declaring the the xml:space attribute and then reference it like this example. The schema from w3c (if you don’t write your own like in the article) is located here.
End-to-end tracing in a SOA
I’ll make this short even if it should be the longest part in this post. Basically we’re trying to archive the following:
Our solution send loads of different messages types between five different BizTalk servers. The client likes to be able to have full text search within these messages and to also be able to see all the messages in each interchange within a server.
So say for example that we receive and Order message in a flat file format. This is transformed in to a Xml message that is then routed down to two other different BizTalk servers. It should then be possible for the client to start an application, click on the Order message type, enter for example the order number (an element i in the message) and see the the full content of the different files within the interchange (in this example that would be the flat file and the Xml file) where that Order number is found.
Basically it’s does what the HAT does (with full text search and a custom GUI). In the first phase of the project we’ll have it work per server, but in the final solution this should perform over all servers … I’ll come back to this in a later post. In the mean time listen to this episode of Hanselminutes on end-to-end tracking. This will be a challenge in every service orientated architecture …
Finally
I’ve sold my iPod Nano and ordered the Creative Vision Zen:M. Now I’ll catch up on all those dnrTV Webcasts! I’ll also make sure to watch everyone of the BizTalk 2006 Webcasts during my commute to work.
Let me know if you found some of this information useful and I’ll try harder to post some like this every Friday.
by Richard | Feb 1, 2007 | BizTalk Community Blogs via Syndication
As I don’t use regular expressions that often I always forget the syntax. So I thought I just put a basic replace pattern up here.
This method takes a schema, finds all places where is says schemaLocation=”whatever” in a text and changes this to schemaLocation=”whatever.xsd“ and then returns the schema.
<div><span style="color: #0000FF; ">private</span><span style="color: #000000; "> XmlSchema FixSchemaLocation(XmlSchema schema)
{
System.Text.RegularExpressions.Regex locationReplacePattern </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">new</span><span style="color: #000000; "> System.Text.RegularExpressions.Regex(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">schemaLocation="(?<location>.*?)"</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);
</span><span style="color: #0000FF; ">string</span><span style="color: #000000; "> locationReplaceValue </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #000000; ">"</span><span style="color: #000000; ">schemaLocation="${location}.xsd"</span><span style="color: #000000; ">"</span><span style="color: #000000; ">;
</span><span style="color: #008000; ">//</span><span style="color: #008000; ">Puts .xsd after the schemaLocation. We need this find the imported schemas</span><span style="color: #008000; ">
</span><span style="color: #000000; "> StringWriter sw </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">new</span><span style="color: #000000; "> StringWriter();
schema.Write(sw);
XmlSchema formatedSchema </span><span style="color: #000000; ">=</span><span style="color: #000000; "> XmlSchema.Read(</span><span style="color: #0000FF; ">new</span><span style="color: #000000; "> StringReader(locationReplacePattern.Replace(sw.ToString(), locationReplaceValue)),</span><span style="color: #0000FF; ">null</span><span style="color: #000000; ">);
</span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> formatedSchema;
}</span></div>
by Richard | Jan 26, 2007 | BizTalk Community Blogs via Syndication
The version redirection in BizTalk do NOT work as one is used to coming from a ordinary .NET developer background (so I was wrong in this post …). Say that we made a reference to a code library in one of our orchestrations. This code library is in version 1.0.0.0 when we build and deploy the orchestration to BizTalk and to the GAC. The setup in VS 2005 looks something like this.
Then we make some minor changes in the code library, we fix them and set the version to 1.0.1.0. Build and deploy it. This means that we now have one 1.0.0.0 and one 1.0.1.0 version side-by-side in the GAC (as shown in the figure below).
Coming from .NET the CLR should now load the 1.0.1.0 version as it identifies assemblies based on the assembly name, major or minor version (NOT the build and revision version), public key token and culture (more about this here).
However, this does NOT work in BizTalk. BizTalk loads assemblies by fullname it has stored in the management database and the build and revision number are part of the fullname … This means we have to build and redelopy EVERY part where we like to use new version of the code library.
There is one way around this for emergency use. Say that one has a code library that is used in loads of BizTalk artifacts (A place where we store all base functionality for the solution). Rebuilding all those parts and redeploying it, just to be able to update the version number, is not going to happened! It’s to much work and to risky. So it’s possible to make a change in the BTSBTSvc.exe.config file instead. In my case the change would be something like the below (read more about here).
<div><span style="color: #000000; "><</span><span style="color: #000000; ">dependentAssembly</span><span style="color: #000000; ">></span><span style="color: #000000; ">
</span><span style="color: #000000; "><</span><span style="color: #000000; ">assemblyIdentity name</span><span style="color: #000000; ">=</span><span style="color: #000000; ">"</span><span style="color: #000000; ">StaticCodeLibrary</span><span style="color: #000000; ">"</span><span style="color: #000000; "> publicKeyToken</span><span style="color: #000000; ">=</span><span style="color: #000000; ">"</span><span style="color: #000000; ">32ab4ba45e0a69a1</span><span style="color: #000000; ">"</span><span style="color: #000000; "> culture</span><span style="color: #000000; ">=</span><span style="color: #000000; ">"</span><span style="color: #000000; ">neutral</span><span style="color: #000000; ">"</span><span style="color: #000000; "> </span><span style="color: #000000; ">/></span><span style="color: #000000; ">
</span><span style="color: #000000; "><</span><span style="color: #000000; ">bindingRedirect oldVersion</span><span style="color: #000000; ">=</span><span style="color: #000000; ">"</span><span style="color: #000000; ">1.0.0.0</span><span style="color: #000000; ">"</span><span style="color: #000000; "> newVersion</span><span style="color: #000000; ">=</span><span style="color: #000000; ">"</span><span style="color: #000000; ">1.0.1.0</span><span style="color: #000000; ">"</span><span style="color: #000000; ">/></span><span style="color: #000000; ">
</span><span style="color: #000000; "></</span><span style="color: #000000; ">dependentAssembly</span><span style="color: #000000; ">></span></div>