Tuesday, 3 February 2009

Give BizTalk some Object Orientation

The following blog discusses the techniques I use for orchestration development that I think are worth consideration...

Coming from a .net and oo programming background I find that although xlang gives you the power, the solutions always lack finesse that a suite of glorious interoperating classes delivers.  

So why not use messages that are .net data types rather than schema based?

Well, although I know you can create messages that have a .net datatype over a schema, that does not mean that you should...

I have found this is to be a far from perfect solution, especially as you lose the magical mapping capabilities that make transforming messages so productive, the mapper does not allow you to pick a .net data type from the type picker.  Also there are some additional advantages to having a schema represented class that I will discuss later.

So having tried to use a pure “messages as.net objects solution”, setting biztalk property attributes on the .net code to create distinguished fields and promoted properties and a whole load of other faf, I came to the conclusion that this is not the way forward. 

Instead I have found that there is a happy medium where you can use the best of both worlds as it suits you, there is however one Golden Rule and several recommendations that I have found useful listed below.

The “Golden Rule” is that all biztalk message variables are based on schemas and not .net objects!  This may seem a little backwards at first, however I found that when you base a message on a .net class BizTalk will create a schema for this class anyway which can be seen in the admin console(I think it examines a serialized version of the object).  If you need to use a schema representation anywhere else (need to map for example) you will have two definitions of the same message within BizTalk and get problems.

So always start with schemas, using these as the basis for your classes.  

When you need to perform some complex work function in BizTalk, generate a .net class using xsd.exe.  You will get a class that represents your schema which you can then adjust as you see fit, adding constructors and object methods that will help perform functions of that class in BizTalk (or elsewhere).  Now there this method gives you some great flexibility discussed later.

No here is my great discovery... You can “Construct” messages by assigning objects directly to them.  What I mean is you can create an orchestration variable that is of type .net class (the class you created using xsd) then assign it directly to a message within a contruct message shape like so....

SchemaMessage = object;

This means that complex message construction can be done in .net which is more suited for this, and simply assigned to a message.  Proper Bo I tell the....

Note however this is not a two way street, in order to assign messages to objects you need to pass the message to a static de-serialization function to create an instance of the object with the message data

object = namespace.object.deserialize(SchemaMessage); - remember the deserialize method will receive an xmldocument

If you are simply using .net for message creation you do not need to worry about custom de\serialization as the xsd generation give you it out of your box.

This interchange is quite neat and means message construction and manipulation within BizTalk becomes a piece of cake.  

Also, and in my view very powerful bonus is that you get the beginnings of a true data dictionary as your class definitions are defined by a set of schemas, forget the M language, .net has had this stuff for ages if you new how to use it! (Don't get me wrong, M is a shot in thearm for this stuff).  You can even use this technique in a non BizTalk environment to help with visual code generation.  

Anyway now you have a class definition of the schema you can reuse it.  What if you were dumping your BizTalk data into a .net application? Bosh, you have got the re=usable objects already.  What if you are creating an application that calls the orchestration using web services? Bam (no pun intended) you have got a class you can create and reuse instead of the web serice proxy generated one, maintaining one central set of class definitions.... Add to this the ability to persist these objects to sql using the serialization and the sql xml data type (in a Dublin-esque way) and my word now we are getting somewhere……  

  • Anyway back to OO BizTalk….

Recommendations

  • only create classes as and when you need them, and always use xsd.exe (its pretty good)
  • Ensure you use the /order parameter of XSD to avoid strange serialization problems
  • Create a batch file for each schema that gets a class and include this in the project
  • If you intend to alter the class (which is likely) write the xsd output to a file that is not part of your project to prevent automatically overwriting any amendments you may have made when running the batch file.
  • Note ALL amendments made in a separate .txt file in case you lose your amended generated file (see above to mitigate the risk of this)
  • Remove\comment out the “specified” Booleans from the xsd generated code, they are unnecessary
  • Remove\comment out the debugger.stepthrough attribute that xsd adds to the class definitions
  • If your schemas have enums, you must set the “AnonymousType = false” rather than true in the serialization xmlTypeAttribute
  • If you make additions to the class, create these in a separate .cs file making use of the partial classes

If you follow my recommendations you will end up with something like the following

A schema\bts project containing

  • MySchema.xsd             

A compoent project containing

  • MySchema_generated.cs
  • MySchema_Extentions.cs
  • MySchema_GenerateClass.bat

Here are some additional style choices I use that may not be everyones flava

I prefer to work with List rather than the arrays that xsd produces.  This still serializes in exactly the same way, but allows you to use the power of List.  You have to implement your own add, count and other functions in order to use this in good ole xLang, but it is easy and neat and I think worth the effort ( I comment out the array and declare a List in my extension class, using the arrays serialization attributes)

Where a class contains a child class, I almost always create a constructor on the child class and parent so that I can use the new operator to give me an object that has values.  Without this you would need to instantiate a child class and set the parent.child = instantiatedchild which is no good.

This means creating a new message looks like this in biztalk

obj = new obj(param1, param2, param3);

message1 = obj;

Quick and simple

Problems

If a schema changes the classes change, that’s how it is.  If you keep a not of all changes and push your additions to a separate .cs file your changes should be minimal (depending on schema complexity).

You have the possibility of increasing the memory footprint for large documents as the object.

Final Thought

It would be nice if a schema had an associated class with it in much the same way as the webservices proxy wizard does but this is not the case at the moment in BizTalk therefore I am rocking with this happy medium which seems to yield the best of both worlds…

Ciao for now

Monday, 21 July 2008

Web Service Wizard

So, I have been working hard of late, getting right into the ole BizTalk, and have come across a couple of issue and solutions that I think are worth a blog....

I have been looking at exposing orchestrations as webservices. A simple and straight forward task as you may think!

However to be typically awkward, I do not like early binding ports (configured during orchestration development) I like my logical ports to be bound to schemas and the freedom of binding to a particular transport mechanism after deployment time during the configuration stage.

Anyway, skip to the end I hear you say....

So while creating a web service to launch my orchestration using the web service wizard, I wanted my web service to be bound to schemas only, and not be created directly from the orchestration. Easy right???

No.

It transpires that the orchestration binding that gets created when the port is wired to a soap port the subscription looks like this

http://schemas.microsoft.com/BizTalk/2003/system-properties.ReceivePortID == {32F1E5D2-04C1-4608-AD01-08019E8BB4DB}
And
http://schemas.microsoft.com/BizTalk/2003/system-properties.MessageType == http://btstest.AsynchSample.MessageHeader#MessageHeader
And
http://schemas.microsoft.com/BizTalk/2003/system-properties.InboundTransportType != SOAP
Or
http://schemas.microsoft.com/BizTalk/2003/system-properties.ReceivePortID == {32F1E5D2-04C1-4608-AD01-08019E8BB4DB}
And
http://schemas.microsoft.com/BizTalk/2003/soap-properties.MethodName == wsTestFunction


Now as you can see, the first subscription is a catch all for everything that is from the port, of the message type and the transport is not soap.

The second is the soap binding. as you can see it is based on the methodName being set to a value (in this case 'wsTestFunction'). This value is actually the name of the operation of the port within the orchestration you are binding to (see below).


Now here is the issue. If you create the web service using the wizard and use schema binding you can name the web service method whatever you like and this may not be the same as the port operation named in your orchestration.

There is a way around this. Open up the generated web service and look at the code for the web service method you have created. You should be able to identify the call to invoke that is responsible for putting your data into biztalk and reading out the result....

object[] invokeResults = this.Invoke("wsTestFunction", invokeParams, inParamInfos, outParamInfos, 0, bodyTypeAssemblyQualifiedName, inHeaders, inoutHeaders, out inoutHeaderResponses, out outHeaderResponses, null, null, null, out unknownHeaderResponses, false, false);

As you can see the first parameter in the Invoke function passes in the name of the orchestration logical port operation. Change this and you are away!

Now once this is edited, your exposed service can have a different name to your logical port. The question you now have to ask yourself is if the service ends up being implicitly bound to the orchestration what is the point of anything!

For that I do not have an answer!

Wednesday, 7 March 2007

And another BizTalk discovery

Having spent the day dealing with this, I found that I got a vision of the guts of BizTalk.

Obviously not being able to identify where these mysterious schemas were going I decided there was stop mucking around and dig into the tables of the managementDB

Having found what looked like a likely suspect hanging around in the BizTalk.Service application I decided to work out how to dispose of this unwanted scumbag of a dll that was causing me grief!

This led to me finding this blog and after significant checking came up with the following snippet that seems to work on 2006

Give it a shot, it worked for me, but do not come crying if BizTalk no worky...

use BiztalkMgmtDB
go
declare @iAssemblyID int
select @iAssemblyID=nID from bts_assembly where nvcName = 'INSERT DLL NAME HERE'
select @iAssemblyID
delete from bt_mapspec where assemblyid = @iAssemblyID
delete from bt_documentspec where assemblyid = @iAssemblyID
delete from bts_item where assemblyid = @iAssemblyID
delete from bt_properties where nassemblyid = @iAssemblyID
delete from bt_sensitiveproperties where assemblyid = @iAssemblyID
delete from bts_libreference where idlib = @iAssemblyID
delete from bts_assembly where nID = @iAssemblyID
Ah what a day, half a day chasing an illussive schema around BizTalk

Problem
We have a BizTalk 2006 project that uses a mixture of schemas and .net serializble objects based on these schemas. Trying to be clever we decided to create port types and messages that were based on the .net type rather than the schema. Circumstances arose where we needed to mix the two up methods (using schemas and .net classes) within one orchestration\project. I kept getting the old message about there benig more than one schema for the inbound message, and I could not find out where this apparant other schema was.

Reason
If you use ports that consume messages that are based on a serializable .net type rather that a schema, biztalk automatically creates a schema for this .net type under the Biztalk.System application, try it, you will see a schema for your .net type appear
.


This type is (obviously) based on a serialized version of the .net type.

Once inside the orchestration, it seems you can use this message as if it were of the type when passing out to helper classes.

Tuesday, 6 March 2007

New PDA

So I have a new love in my techno life. My new PDA. It is the nuts, it is an HTC P3350 running on T-Mobile.


A whole new chunk of technology for me to get my teeth into and blog about.


Discoveries so far....


T Mobile have chosen to lock the wifi functionality for reasons unknown. I guess it stops me installing a skype client and stopping use their air time, along with forcing me to use their soo slow gprs!

Soooo. why is this phone the daddy. Well it has built in GPS which means I can begin to look into location specific functionality without having to use the cell triangulation which most providers do not allow easy access to...

More to come soon

Tuesday, 27 February 2007

The blog is up

Finally got around to creating a blog.

Been contemplating it for a while and finally figured I would give it a bit of my time. Hope it is worth while to somebody out there. Will divide it up into a couple of areas, but will try to write as often as possible! lets hope I can maintain the enthusiasm

Better late than never is