In BizTalk development we all know that there is a reasonable amount of .net coding which goes into most solutions. This may be in the form of custom BizTalk widgets such as custom pipeline components or helper classes to contain some logic you might call from a map, orchestration or pipeline. .net development often uses approaches such as Inversion of Control (IOC), Dependancy Injection (DI) and Service Locator to help implement solutions. Castle Windsor is one of the open source components which is commonly used in .net projects to implement these patterns and in this article I wanted to talk a little about how we can use Castle Windsor in a BizTalk solution.
In short these approaches are about changing the way you write your .net code to break dependancies between objects and how instances of objects are obtained. The main aims and benefits of this are:
- Reduce complexity by simplify dependancies
- Make code easier to test
- Support dynamically loading objects
- Support adding Aspects to objects
These are all good things so they should be things we consider which may help us build better solutions.
Before we get into this article any further if you feel you need to understand additional background info please refer to the following links:
|Inversion of Control Containers and Dependancy Injection||http://martinfowler.com/articles/injection.html|
|Basic Windsor Tutorial||http://docs.castleproject.org/Default.aspx?Page=Basic-Windsor-Tutorial&NS=Windsor&AspxAutoDetectCookieSupport=1|
|Castle Windsor Tutorial||http://app-code.net/wordpress/?p=641|
|A guide to IOC with Windsor||http://www.makecodingeasy.com/a-guide-to-inversion-of-control-with-castle-windsor/|
In my BizTalk code base if you imagine if I have a code structure something like the below:
- Acme.MyBizTalkApp (VS Solution)
Contains the BizTalk artefacts for this small BizTalk app
Contains some helper classes to support the artefacts in the Acme.MyBizTalkApp assembly
Contains some generic utility classes for this application which will be reused as the code base potentially grows in the future
Contains some reusable framework classes which could be used by multiple BizTalk applications. Note to keep things simple in this demo we are just using these with this app
I know there are a few different ways that people implement their code structures but the above is quite common so lets use that as an example. In this example we may have some classes in any of the utilities components which could be used in various parts of the solution. If we imagine that we have one of these BizTalk components which will use some .net objects and in this article we will walk through how we can break up the dependencies between those objects using Castle Windsor.
Challenges for using Castle Windsor in BizTalk
Castle Windsor is commonly used in a lot of .net projects but development in BizTalk is a little different. If your writing a custom application such as a windows app, a web app or a web service then your setup to start using Castle Windsor is pretty straightforward but with BizTalk it is not quite as simple. Some of the challenges are discussed below.
Managing and Deploying
The first challenge is that in BizTalk you have the GAC involved and are not deploying to something simple where you just need assemblies in a bin directory. With this in mind you need to consider how you will get your reference to Castle Windsor and how you will deploy it so that it can be used by BizTalk solutions. I have put together an approach for this in a previous blog article which discusses this on the following link:
Loading the Container
The next challenge come when you want to load the container so that you can make it away of the Types it will be able to resolve references for. In an IIS hosted application you would probably implement something like a handler so you can load it on the apps initialization. The other choice is to load the container each time you want one which is a more expensive operation or finally you could wrap your container in a singleton pattern so it is loaded once. In BizTalk there are no initialization events you can hook into so you need to use one of the other two options.
Registering types with the Container
You can register an object with the container at runtime from your code anytime you want, but normally the approach taken is when the container is loaded you would use one of the following approaches:
- Reference a configuration file which tells the container which types to load and which assemblies they implement
- Tell the container which assemblies to scan to find installer classes where you can code your own logic to register the dependancies
While the configuration file approach can work ok for .net projects if you are following best practices then you should be implementing a full versioning approach of your assemblies and this means that when they are deployed to the GAC you will need the full strong name of the assembly in the config file. This gives us a problem because the version number will change with each build so it is going to be awkward to keep updating the configuration file. Based on this problem I think the scanning of assemblies is a better approach for BizTalk but you do not want to create un-necessary references between projects so if you supply a full strong name of the assemblies you want scanned then the container will do this for you without having to create new references.
The strong names are still going to change with each build but I thought of a good way to handle this which Ill discuss later.
One point to be aware of is that normally developers are using Castle Windsor in IIS or Custom processes. In BizTalk I think the way threads are managed and reused is something to be aware of as this could be a factor to consider when you do certain things.
Lets now do a walk through of the solution example I have put together.
The IOC Container
In the AppFx.BizTalk.Utilities project there is a folder called Ioc which contains all of the classes which I use to internally contain my implementation of the Castle Windsor container. The main classes are:
|ApplicationContainer||This is a simple wrapper around the IWindsorContainer interface to provide some helper methods and logic to simplify the use of the container|
|BizTalkApplicationContainer||This inherits from ApplicationContainer and adds some additional logic around using the container in a BizTalk context. In particular it encapsulates the container loaderpattern I have implemented which uses the BizTalk config file to determine how the container should be loaded.|
When you want to use the container in your application you would implement a class which has a singleton instance of the container for your application. An example of this can be seen in the Acme.MyBizTalkApp.Utilities project in the AppContainer class. In this class I specify a name for my container and implement a singleton around the use of a BizTalkApplicationContainer. When I construct the instance of BizTalkApplicationContainer passing in its name will cause it to load the container based on the way it has been configured.
Note that you do not need to manage the container as a singleton but each time it is loaded there will be some overhead to load it before using it so a singleton is probably the best default approach.
Loading the Container
When the container is loaded your AppContainer will create an instance of BizTalkApplicationContainer which you will probably manage as a singleton. By creating this class you will pass in a name which is then internally resolved against the BizTalk configuration file. In this file you will see something like the below example:
In the config file a custom config section is implemented which defines a named container. For that container it specifies the method that can be used to load the container via the loaderType property. I have implemented the following types:
|BRE||A Business Rule defined by the load key will be executed to get a list of assemblies which will be scanned for Castle Windsor installers to load the container|
|CONFIG||A list of assemblies will be included in the configuration file which will contain a list of assemblies which will be scanned for Castle Windsor installers to load the container|
|CUSTOM||A custom class will be specified in the loader key which will be used to identify which assemblies to scan for Castle Windsor installers to load the container|
|NONE||No loader will be executed and the developer will manage registering types with the container himself|
While there are a number of options to load the container some will be more suited for test scenarios and some for production. Unfortunately as I mentioned earlier there are events we can hook into to pre-load the container so we will load it up on first access and there will be a small overhead to load the container the first time it is set up.
In this example I have chosen to use the BRE loader. The main reason for this is that I know that I am likely to be implementing a full versioning approach in my solution and I know I can fully strong name then in the BRE policy I can manage this as an xml file within my solution and then in this policy I can specify a list of assemblies which should be scanned for installer classes to load the container. The below picture shows the BRE policy.
You can see that the policy is pretty simple. In the conditions I simply specify an always true condition then in the actions I pull in the AppFx.BizTalk.Utilities which contains a class called ContainerContents in the AppFx.BizTalk.Utilities.Ioc.Loaders namespace. This class contains a method called AddAssembly which I call and pass in a string which is the strong name of the assembly I want to scan. I can simply repeat this action multiple times to list all of the assemblies I want to get scanned when loading this instance of the container. This also means that the container will scan those assemblies without having to create any kind of reference between my projects.
It would be likely in my policy that I will include most of the .net assemblies that make up my solution so that they are all scanned to run any installer classes. I may also choose to add some other assemblies which are reused across BizTalk projects.
When an assemble is scanned during the loading of the container at runtime it is looking for any classes which implement the IWindsorInstaller interface. You can have many of these across your solution located in places that are appropriate. A simple way to do this could be to have one installer class per project or you may have more than this if your solution is very complex. You will see an example of the installer in the Acme.MyBizTalkApp.Helpers project inside the Installers folder. In this installer I have specified that there are two interfaces:
For these two services I have defined in the installer which class will implement these and registered them with the container. This means later at runtime you can request an object which can provide the IClaimValidator service from the container without having to be aware of the concrete class which implements it.
The below picture shows an example of the installer:
Accessing a Type
Once we have the logic lined up to load our container this will happen automatically behind the scenes the first time we access the container to get an object. In the code base I have defined an orchestration called ClaimsValidationProcess. This will access a helper class called ClaimsValidationProcessHelper. As a general rule I normally create a single helper class for each orchestration to act as a facade to any .net logic I choose to access within the code base. I have found this is a good way to keep your code base cleaner rather than accessing methods on objects all over your code base. In the orchestration we will off load calls to the helper class when we want to request some stuff to be done in .net. In this case the helper class will implement some basic functionality to validate the claim and build a response message. I could choose to implement all of this logic in line within this class but then I make this helper class big and difficult to test. Instead I can implement some small classes which will encapsulate these requirements and use an interface to expose them. The helper class will request the services it needs via the container and I can provide the implementations that have been loaded into the container as the implementation of the logic requested. At runtime this will be what ever the business rule caused to get loaded as the real class, but at unit test time I could replace the class with a mock object to make testing of the helper class a lot simpler.
If you take a look at the below picture then you can see some examples of accessing the types you may need:
At this point what we have done here isnt that different to how developers use Castle Windsor in the .net world. The main difference is that I have created a way which you can more easily use it within your BizTalk development by providing the BRE loader as a cool way to handle the BizTalk challenge of loading the container with dynamically versioned assemblies. Even if you are not using dynamically versioned assemblies you could still use this approach and manage the loading yourself through the configuration file or through a custom approach.
In the walk through I did not go too much into ways the IoC approach could be cool with BizTalk, I wanted to provide a relatively simple walk through just showing that it can be done which opens up some opportunities.
Where might I use Castle in my BizTalk solution?
I think some of the key areas and benefits of using the Castle approach here include:
- Making it more testable
In the walk through I have shown how breaking dependancies between my objects can make the code base simpler. In a future article I will explore some of the opportunities this allows to help me test BizTalk.
By accessing objects in a more dynamic approach I think this will open up some patterns to be able to dynamically change the behaviour of your software at runtime. Perhaps you may be executing some logic and you could call out to the BRE and it could return you a key indicating which of multiple objects registered to implement an interface should be used. This could also allow you to develop plug in type patterns.
- Helper Classes
I think the most obvious opportunity is anytime your developing helper classes you can consider if there are potential benefits to using the container to break out dependencies between them. This probably covers helpers for Pipeline Components, Maps, Orchestrations
To complement the above I have a video walk through below:
The code sample is available at the following link:
I hope this article provides some useful thoughts for people on things you could potentially do by combining Castle and BizTalk.