A source code could be downloaded from here.
Global artifacts are usually tentative things. Languages and tools have different methods to limit the artifact visibility. Think about public and private variables, for example. BizTalk limits the artifact visibility usually by the assembly (project) boundaries. For example, the port types, the correlation set types. The BizTalk applications were introduced as containers for artifacts and they naturally limit the artifact visibility. Artifacts are not visible outside of an applications by default.
But sometimes in BizTalk the artifact visibility can be global. We place the artifacts in different assemblies and it doesn't limit the global visibility. We place the artifacts in different BizTalk applications and it doesn't limit the global visibility. I am talking about schemas. In my previous post BizTalk: Internals: namespaces I've shown that schemas have additional parameter, the Xml [target] namespace. Why it is so important? The BizTalk receives messages on the Receive Locations. Theoretically messages are just the byte arrays. But the BizTalk frequently has to do additional tasks like changing the message format from the one system format to another. In this case a message should be received in the well-known format. Without knowing the message format the BizTalk cannot make not the message validation nor the message transformation. (The BizTalk message internal format is an Xml or a byte array. Here I am talking about the messages in the Xml format.) So the Xml messages are received by the Receive port as the byte arrays and should be parsed into Xml format. The XMLReceive pipeline makes this transformation. The first thing the XMLReceive makes, it searches a Xml namespace and a root node. Those two parameters create a MessageType parameter with is promoted as a context parameter.As you can see, the BizTalk uses the MessageType to find out the schema for this message. This Xml schema is used to parse the whole message into Xml format. So the first step is to find a Xml namespace and a root node inside the byte array regardless of anything else, the second step is to find out the Xml schema inside the schema repository, then this schema is used to parse the whole message into Xml format. Now we are discussing the second step, how the BizTalk is searching the right schema. The BizTalk searches through the whole schema list regardless of the application boundaries. Each schema belongs to one of the BizTalk application, but BizTalk ignores this. The global schema list is stored inside the BizTalk management database. When we deploy a project with a schema, the schema is registered inside this database. When an inbound message is received and processed by the XMLReceive pipeline, the BizTalk extracts a MessageType (a namespace + a root node), and searches for this MessageType in the management database. An error is raised if the MessageType is not found. The error is raised if more than one schemas with this MessageType is found.
An important note is the schema uniqueness rule is not verified at the deployment time. I have created several samples to show how it works. These samples are bare-bone projects, focused on the “schema uniqueness” rule.
The application includes two projects. Each project is compounded from one schema.
Both schemas have the same structure and the same Xml namespaces.
The only difference is the .NET namespaces. Each schema is placed in different assembly.
I have created one receive port with one File receive location and XMLReceive pipeline. A send port works as a subscriber to this receive port.
Nothing else is in this application. Two identical schemas in different assemblies and receive and send ports.
I dropped a test Xml file in the receive folder. What do you think is happened? You are right, I've got an error and two related events, 5753 and 5719.
It is a famous "Cannot locate document specification because multiple schemas matched the message type ###" error. :)
Conclusion: schemas of the receive messages should be unique across all BizTalk application.
Now two the same projects are in different BizTalk applications. (As you can see I have broken the naming convention, which forces to place the BizTalk applications in the different Visual Studio solutions. In real life there would be two Visual Studio solutions. Sorry for that. )
The ports are the same as they are in the first sample.
When I dropped a test file I have got the same error as in the first sample. So the schemas are now placed in different applications but it doesn't change the schema visibility. The schema from one application is visible from another application.
Conclusion: schemas of the receive messages should be unique in different BizTalk applications. In other words they should be unique across the whole BizTalk Server Group.
Now let’s ask a question. Is the “schema uniqueness” rule relating to the imported schemas?
Here is a real-life example. We are consuming the WCF web-service metadata, and it creates the schema set where we can see the Microsoft Serialization schema. It is the same schema almost in each and every WCF service. Do we have to take care of this schema if we consume several WCF services? Do we have to “fight” this schema, extract it into Shared project, etc.?
This sample is the same as a previous sample with two additional schemas: Importing.xsd and Imported.xsd.
Both Importing schemas in two applications are different. They have different Xml namespaces.
But both Imorting schemas are identical.
The ports are the same as they were in the first sample.
When I dropped a test file there was no error.
So the “root” schema namespaces, the namespaces which define the MessageType were different, but the namespaces of the imported schemas were the same and this the XMLReceive pipeline could successfully recognize the MessageType of the message.
Conclusion: the “schema uniqueness” rule works only for the schema which define a MessgeType of the received message and doesn't work for the imported schemas.
Is there a good reason for this rule?
Looks like a reason for this “schema uniqueness” rule is simple. The BizTalk application was introduced only in the BizTalk 2006. In this time Microsoft decided do not change the XMLReceive and XMLTransmit pipelines to embrace new application conception and since then this feature was not on the priority list in the BizTalk development.
I would prefer if the schema visibility is limited inside the BizTalk application. It would extremely simplify the schema and service versioning.
Let’s take an example when our partner added a new version of the service. The service schemas itself are different in both services (several nodes were removed, several nodes were added), but the schema namespaces and roots are the same in both services. The new and old services work side-by-side and we have to consume both service versions. If we could limit the schema visibility inside the application boundaries, creating the BizTalk applications for consuming both service versions would be simple. Now it is cumbersome. I am sure, each experienced BizTalk developer can remember several real-life examples, when this “schema uniqueness” rule was a reason when several hours project was instead implemented in several days.