Integration Challenge: BizTalk Functoid Blues

Recently I was facing an integration challenge by creating a custom functiod to use in a mapping. How do I create a custom functiod? Well one can look at a sample on a machine, where a BizTalk instance is present (usually C:\Program Files\Microsoft BizTalk Server 2006\SDK\Samples\XmlTools\CustomFunctoid). Important is to import the BizTalk assembly: Microsoft.BizTalk.BaseFunctoids. This one can be found on the server containing the BizTalk instance in folder: C:\Program Files\Microsoft BizTalk Server 2006\Developer Tools. So you can start creating a custom functoid by creating an empty solution. In that solution one adds an empty project. Why this way, well if you want to create a custom functoid the same way as in the sample, starting off with a class library template in Visual Studio will give you a different set of things like properties. After adding the empty project, change properties of project to class library. Next create a strong name through properties, the assembly will later be added to the GAC. Add namespace will useful name (assembly and default namespace, both the same). Add a class to the project and give it a useful name. Next is to add a couple of assemblies as reference, starting with Microsoft.BizTalk.BaseFunctoids, System and System.XMl and System.Data. These will be used in the class, together with some other. Finally before implementation an empty resource file has to be created. This can be done by downloading the following tool: resourcer found here. By adding an empty resource file to your project one can later add some string values and a bitmap. Why doing it this way, which may seem like a lot off overhead.
















Creating a resource fill happens differently inside VS 2005 and System.Drawing has to be added and another file is added in the background resource.designer.cs, something you don’t want, because it will muck up adding the functoid in the end to your functoid toolbox (at least that is what I experienced).

Implementation

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using Microsoft.BizTalk.BaseFunctoids;


namespace namespacename
{
///
/// myCustomFunctiod will assert if node from xml document contains an empty value (string).
///

public class myCustomFunctiod : BaseFunctoid
{ public myCustomFunctiod () : base()
{ //ID for this functiod
this.ID = 5001;

// resource assembly must be ProjectName.ResourceName if building with
// VS.Net
SetupResourceAssembly("namespacename.ResourceFileName", Assembly.GetExecutingAssembly());

//Setup the Name, ToolTip, Help Description, and the Bitmap for this functoid
SetName("IDS_MYCUSTOMFUNCTOID_NAME");
SetTooltip("IDS_MYCUSTOMFUNCTOID_TOOLTIP");
SetDescription("IDS_MYCUSTOMFUNCTOID_DESCRIPTION");
SetBitmap("IDB_MYCUSTOMFUNCTOID_BITMAP");

//Set number of parameters
this.SetMinParams(1);
this.SetMaxParams(1);

//set the function name that needs to be called when this Functoid is invoked. This
//means that this Functoid assembly need to be present in GAC for its availability
//during Test..Map and Runtime.
SetExternalFunctionName(GetType().Assembly.FullName, "namespacename.myCustomFunctiod", "FunctionName");

//category for this functoid. This functoid goes under the String Functoid Tab in
//the VS.Net toolbox for functoids.

this.Category = FunctoidCategory.String;
this.OutputConnectionType = ConnectionType.AllExceptRecord;
AddInputConnectionType(ConnectionType.AllExceptRecord); //first input
}

///
/// this is the function that gets called when the Map is executed which has this functoid.
///

/// myParameter
/// something
public string FunctionName(type myParameter)
{ //myFunction Implementation }
}
}

String values for the functoid like name, tooltip can be added by double clicking the resource file in the project inside VS 2005. Add the exact string name as in your code and use string values for name, tooltip and description. The bitmap can be custom made by for instance using paint.

Deployment of functoid

Before deploying your functoid go to project properties and click assembly information. One will get a form like picture below. Fill in title, description ect. Important here is GUID!!!! Create one by going to tools--> Create GUID. Build your solution/project after this. Add assembly to GAC and copy assembly to folder : C:\Program Files\Microsoft BizTalk Server 2006\Developer Tools\Mapper Extensions.



















Deployment can be automated by using script like this:

@SETLOCAL

@CALL "%VS80COMNTOOLS%vsvars32.bat"

@SET SolutionName=myCustomFunctoid.sln
@SET AssemblyKeyFile=myCustomFunctoid.snk

@ECHO.
@ECHO If key files is not found, will generate a new key file...

@IF NOT EXIST %AssemblyKeyFile% sn -k %AssemblyKeyFile%

@ECHO.
@ECHO Building the project...

@DevEnv %SolutionName% /build Debug /Out Build.log

@COPY bin\Debug\myCustomFunctoid.dll "..\..\..\..\Developer Tools\Mapper Extensions"

@ECHO.
@ECHO We need to GAC the .NET assembly that will be called
@GacUtil /if bin\Debug\myCustomFunctoid.dll

@ENDLOCAL

@PAUSE


Adding functoid to toolbox

Final step is to add the functoid to the toolbox.




I hope this will help to you to create functoids, when you need to create them. This can be the case, when functionality wanted in maps concerns a couple of out of the box functoids together and repeatedly. For better overview your map will not be crowded with numerous functoids when combining all functionality in one functoid; this can be helpful! Another reason might be functionality you want is not there. There is another great article on the web, where building a custom functoid is explained in case one needs some desired functionality that comes not from a out of the box functoid. Together with this post and that article you will have a great inside in developing your own functoids.

Technorati:

Labels: , ,