
Understanding the solution at runtime
Earlier we saw a package diagram representing a typical BizTalk solution and in the previous chapter we discussed how BizTalk uses the management database and the GAC to load solutions. How this all works is a fairly important aspect of our solution architecture and of BizTalk so we'll now have a quick stroll through this process. The actors involved are as follows:
- BizTalk runtime (.NET runtime)
- Message box
- Management database
- Global Assembly Cache (GAC)
Of these, the only one that we have not covered is the GAC. The GAC is a core feature of the .NET framework and was created to address the shortcomings of COM architectures. The GAC is a database or repository of .NET assemblies installed on a machine; hence the global part of the name. The GAC is responsible for making sure that we don't experience the pain of versioning and management that often accompanies COM DLLs (colloquially referred to as DLL Hell). To accomplish this, the GAC enforces several constraints on assemblies, the largest being that they must be Strongly Named. This is accomplished through the assembly manifest; metadata about the assembly itself; specifically a combination of the name, version number, digital signature, and culture.
This means that assemblies for BizTalk solutions must be strongly named. That's why we talked about keys before; we use them to strongly name assemblies. This mechanism gives us an explicit method for defining versions of assemblies. The default version for an assembly in .NET is "1.0.0.0". These four sections of the version number correspond to the following: [Major version].[Minor version].[Build version].[Revision version]. The idea is that the numbers will count up with the left-most numbers changing the slowest and the right most changing the fastest. The .NET framework itself reflects this in the v1.1 and v3.5 releases, where 3.5 was major version 3, minor version 5.
This whole apparatus allows .NET applications to load types at runtime secure in the knowledge that the types will be what they expect (or at least conform to the same interface). An added benefit is that this arrangement also allows for multiple versions of assemblies to coexist safely with each other.
The following diagram depicts the way this is used by BizTalk to load our solution. The steps are labeled in the diagram. It is intentionally a simple example:
- When a message arrives in BizTalk, the host instance (BizTalk runtime) that receives the message inspects the message to see if it matches a known message type. The list of known types is stored in the management database.
- After finding a matching message type, the runtime then loads the assembly containing this type from the GAC.
- The runtime is now free to use the loaded .NET type which can be a schema, map, pipeline, or orchestration.
The diagram shows how BizTalk resolves the message type and loads the schema representing that message type from the Global Assembly Cache. A final note of importance is that this loading from the GAC only occurs one time for each type during the lifetime of a host instance. This means that after the first load, the process is considerably faster. This is a part of the cache portion of the name. If you restart a host instance, which is to say restart the windows service for that host instance, you have to shut down the old process and the types will again load on first use. Some assemblies in BizTalk will also unload after extensive periods of idle time.
Every .NET application that uses the GAC doesn't actually run the assemblies from the GAC, it copies them to its own working area so that the GAC can be changed and updated without interfering with running processes. This allows us to register replacement assemblies in the GAC without first stopping the processes that are currently using those assemblies. The drawback is that a replacement assembly will not be loaded until the application domain (a sort of lighter weight version of a process that lives within a process) is reloaded; this generally means restarting the host process; that is, the BizTalk runtime. That said, newer versions with different version numbers can be deployed and loaded without restarting the process in a side-by-side manner. This means that when planned carefully a BizTalk application can be upgraded in place without any downtime. Carefully planned is the key operative here.