There is no necessity to explain the importance of caching in any server based developments like BizTalk, ASP .NET etc. You need to plan early in your development cycle to cache resources in order to make most out of your limited server resources.

In BizTalk applications, it’s quite common to lookup a data store to pickup a value, at different stages like custom Adapters, Pipelines, Orchestration, etc. The data store could be a custom SQL database/table,  a XML File, Active directory etc etc. Whatever the data store is, if you are doing the lookup for every message you process without any caching, its going to be an expensive and useless operation.

Due to the nature of BizTalk architecture, its very easy to implement a caching logic just with a static class and a static method as shown below:

public static class CacheHelper
    {
        private static Dictionary<string, string> _authorIds = null;
        public static string GetAuthorName(string authorId)
        {
            if (_authorIds == null)
            {
                Debug.WriteLine(“Cache is empty. So populating the cache…”);
                _authorIds = new Dictionary<string, string>();
                lock (_authorIds)
                {
                    _authorIds.Add(“2FC0CF1D-E107”, “Matthew Johnstone”);
                    _authorIds.Add(“71F5C860-80FA”, “Carl Reynolds”);
                    _authorIds.Add(“158FF294-1A89”, “Robert Perkins”);
                    _authorIds.Add(“A71AE681-9C39”, “Michael Killey”);
                    _authorIds.Add(“58794661-A9A3”, “Saravana Kumar”);
                }
            }
            else
            {
                Debug.WriteLine(“Cache list is pre-populated. Value is going to be taken from the cache.”);
            }
            string authName = _authorIds[authorId];
            if (authName != string.Empty)
                return authName;
            else
                throw new Exception(“Author cannot be found with id :” + authorId);
        }
    }

In .NET static variables are maintained per Common Language Runtime (CLR) “AppDomain”. We can just exploit this behavior of .NET for our caching needs. In BizTalk world by default there is only one “AppDomain” per BizTalk host. So, all your custom BizTalk applications will be running under this default host (AppDomain) and they all share the static members. This means any subsequent executions will make use of the cached values.

In the above code snippet, I just added few Name-Value pair items to “authorsIds” collection, in real world scenarios we might need to populate them from a data store like SQL database. If we are doing that database lookup for every message, then its going to be unnecessary roundtrip’s to the database and wastage of server resource.

This utility class can now be used in any of your custom BizTalk solution like Adapters, Pipelines, Orchestrations etc.  The following Orchestration shows its usage.

The message assignment shape got the following lines of code.

MSG_AUTHOR_OUT = MSG_AUTHOR_IN;
MSG_AUTHOR_OUT.Name = Utility.CacheHelper.GetAuthorName(MSG_AUTHOR_IN.Id);

When I Build, Deploy and run the sample, for the first message the DebugView showed the following output:

For subsequent messages (I posted 4), DebugView showed the following output:

You can make sure the cache is repopulating by restarting the BizTalk host instance (NT Service).

NOTE: If you are using isolated adapters like HTTP/SOAP the data will be cached under the IIS worker process, so to reset the cache you need to reset IIS.

This technique is simple to implement and easy to use. If you want more advanced caching like cache expiration, dependency etc then you can consider using Enterprise Library caching application block.

Download the full sample here.

Nandri!

Saravana