A colleague of mine, Morten la Cour Thomsen, who is "MCTS: BizTalk Server 2004" AND "MCTS: BizTalk Server 2006" discovered something strange the other day. In fact, it is so strange, that I thought I'd share it here on my blog.
Morten was on a project, where he had taken over another persons BizTalk solution. Unfortunately for Morten, the other guy had decided to put all artefacts into one single assembly. That's right - all schemas, all maps, pipelines, orchestrations.. the works! Just one big assembly.
This turned out to be quite a problem for the company that had this solution, since versioning any single artefact meant versioning the whole thing. That is also why they until now didn't version anything. Should something need to be changed in the big assembly, four steps were performed:
- Stop all receive locations
- Make the change in the artefact that needed changing
- Wait until all long running transactions have stopped
- Deploy the new assembly on top of the old one, leaving all versionnumbers the same
Mortens job was to create a better architecture, since it really wasn't ok with the customer to have to stop receiving new messages until all orchestrations had stopped.
One of the steps Morten came across was that he actually at some point needed to call an orchestration that was inside this big assembly. The orchestration that Morten needed to call was being called from other orchestrations inside the assembly, so it was ready to be called (no activate receive shape, etc.). The only problem for Morten was, that the orchestration, off course, was internal to the assembly. Morten could reference the assembly, but he couldn't call the orchestration from within an "Call Orchestration"-shape.
But that's when Morten tried something that I would never have thought of trying: He had the source code for the big assembly. And he had the keyfile that had been used to sign it. So he changed the orchestration to be public, recompiled the big assembly, referenced the newly compiled assembly, added the former internal orchestration to his "Call Orchestration"-shape and compiled his own assembly.
He now deployed his own assembly, but left the old big assembly in place.
Now he had the old big assembly, which still had the internal orchestration inside it. And he had another deployed assembly, which was compiled against the source code with a public orchestration. The big assembly was never redeployed!
But it worked! Mortens orchestration is now calling the internal orchestration of the other assembly, simply because it was compiled against a public orchestration and the signature of the deployed big assembly matches the signature of his newly compiled big assembly.
Very weird, indeed. And it probably isn't meant to do that...
I have a sample solution for BizTalk 2004 you can look at right here: InternalOrchestration.zip (132 KB)
And two sample projects for BizTalk 2006 right here: Calling Internal Orchestration.zip (146,46 KB)
In both cases, the code reflects the internal orchestration AFTER it has been set to public. What you want to do is to
- Set the type to "internal" on the called internal orchestration.
- Build and deploy the assembly with the internal orchestration.
- Test it to see that it works.
- Try to build the other assembly. It will fail because of the internal orchestration.
- Set the type to "public" on the called orchestration.
- Build and deploy the second assembly WITHOUT redeploying the first assembly.
- Test it to make sure it works.
So, basically, now you have a way of calling an internal orchestration, as long as you have the source code for it and the key to sign it.
Hope this is useful for someone.