Writing Custom Biztalk Functoid

Introduction to Functoids

I am sure you have heard about functions, but what about functoids?
Functoids or BizTalk functoids are, in a way, small reusable functions that
you build just like functions. These are like operations that you need to
perform specific tasks on data. BizTalk comes with a good collection of
readymade functoids. But you will frequently face situations where you
desire a simple functionality. Let us say, you want to validate a credit
card number, it will be great if we can build a functoid which can take in a
credit card number and credit card type, and return true or false. This will
be a very good scenario for writing a functoid of your own.

Scenario

As a learning exercise, I suggest building a functoid which calculates
the perimeter of a rectangle for a fencing company. The logic of the
functoid implementation is really concise:

2   x (length + breadth)

A Bird’s Eye View of the Steps

To create a BizTalk functoid, we need to briefly do the following:

  • Derive our functoid from Microsoft.BizTalk. BaseFunctoids.
  • Give it all resource strings like function name, function bitmaps to
    be displayed in the mapper, tool tip text, and description.
  • Give it a unique GUID and a functoid ID.
  • Specify what category the functoid belongs to (Math, Logical, String
    etc..).

  • Specify input and output parameters.
  • Specify the input and output connection types.
  • Specify the function to call.

Getting Down to Business ..

I have broken down the activity into a series of logical steps.

Step 1: Creating your functoid project

You need to create a functoid as a class library. So we need to select a
class library project to begin. Make sure you give a proper namespace name
for it as we will need this to load the functoid later, using Reflection. We
will use Custom.Biztalk.MathFunctoid as the namespase in our
example:

Step 2: Signing the DLL with a key

You need to have a strong name for this assembly to get it loaded into
the toolbox. So create a strong name and sign it:

C:SamplesMathFunctoid > sn   -k mathFunctoid.snk

Once you have the strong key generated, insert the line below to the
AssemblyInfo.cs
:

[assembly: AssemblyKeyFile("..\..\ mathFunctoid.snk")]

Step 3: Give a unique ID for this assembly

We need to give a unique ID for this assembly. Using GUIDGEN from the
Visual Studio prompt, generate a new GUID and add the following to the
AssemblyInfo.cs
:

[assembly: Guid("5DE500CC-45BC-454b-A23D-24449899042C")]

Step 4: Add the class skeleton

We need to have a class to implement this functionality, so add a class
and call it CPerimeter (or any meaningful name of your
choice)
:

Once the class is added, add the following lines in the namespace
inclusion section at the top of your class file:

using Microsoft.BizTalk.BaseFunctoids;using System.Reflection;using System.Globalization;using System.Resources;

Step 6: Add references to BizTalk base functoids

In the project references, add a reference to
Microsoft.BizTalk.BaseFunctoids.dll
. This DLL implements all the base
classes we need to create a functoid.

Step 7: Add a resource file

In Visual Studio, go to File->Add New Item->Resource File.

I named the resource file Mathresource.resx for this example. Now,
add the following resource strings and specify their custom descriptions:

Resource ID Value Explanation
IDS_CONVERTINTFUNCTOID_ID 6123 A value greater than 6000
IDS_FUNCTOID_NAME “Perimeter” The functoid description in toolbox
IDS_MATHFUNCTOID_TOOLTIP “Calculates the perimeter of a rectangle” What appears on the tool tip
IDS_MATH_DESCRIPTION “Calculates the perimeter” Description of functoid in VS
IDS_PERIMETERFUNCTOID_EXCEPTION “Perimeter functoid threw an exception” Description of exception to the Biztalk subsystem

Now, create a 16 x 16 bitmap and add that to the resource file, and
reference it as IDS_MATH_BITMAP using the Resource Editor.

Step 8: Implement the class

To implement this class, we derive our class from BaseFunctoid.
And in the class, we load the resource file, and set the different
parameters like functoid name, tool tip text, and parameters for the
functoid.

public class CPerimeter : BaseFunctoid{    static ResourceManager resmgr = new    ResourceManager("Custom.Biztalk.MathFunctoid" +      ".MathResource", Assembly.GetExecutingAssembly());

    public CPerimeter():base()    {        int functoidID;        functoidID = System.Convert.ToInt32(          resmgr.GetString("IDS_CONVERTINTFUNCTOID_ID"));        this.ID = functoidID;

        // This has to be a number greater than 6000        SetupResourceAssembly("Custom.Biztalk.MathFunctoid" +            ".MathResource", Assembly.GetExecutingAssembly());

        //Set Resource strings , bitmaps        SetName("IDS_FUNCTOID_NAME");              SetTooltip("IDS_MATHFUNCTOID_TOOLTIP");        SetDescription("IDS_MATH_DESCRIPTION");        SetBitmap("IDS_MATH_BITMAP");

        // Minimum and maximum parameters        // that the  functoid accepts 

        this.SetMinParams(2);        this.SetMaxParams(2);

        /// Function name that needs to be        /// called when this Functoid is invoked.        /// Put this in GAC                            SetExternalFunctionName(GetType().Assembly.FullName,                    "Custom.Biztalk.MathFunctoid.CPerimeter",                    "CalcPerimeter");

        //Category for this functoid.        this.Category = FunctoidCategory.Math;

        //Input and output Connection type        this.OutputConnectionType =             ConnectionType.AllExceptRecord ;        AddInputConnectionType(ConnectionType.AllExceptRecord);    }}

Step 9: Implement the function logic

Now, we implement the functoid logic for the function name specified in
the above step, using SetExternalFunctionName. The code below
trims the incoming values. This is done because in XML, string data that are
numerals could contain white spaces.

public string CalcPerimeter(string RectangleLength,                            string RectangleBreadth){    int ilength = 0;    int ibreadth = 0;    int iPerimeter = 0;    ResourceManager resmgr = new ResourceManager("Custom." +                             "Biztalk.MathFunctoid.MathResource",                             Assembly.GetExecutingAssembly());

    //Remove whitespace    RectangleLength = RectangleLength.Trim();    RectangleBreadth = RectangleBreadth.Trim();

    if ( IsNumeric(RectangleLength) && IsNumeric(RectangleBreadth) )    {        try        {            ilength = Convert.ToInt32(RectangleLength,                      System.Globalization.CultureInfo.InvariantCulture);            ibreadth = Convert.ToInt32(RectangleBreadth,                       System.Globalization.CultureInfo.InvariantCulture);            iPerimeter = 2  * (ilength + ibreadth);        }        catch        {            throw new Exception(string.Format(resmgr.GetString(                                "IDS_PERIMETERFUNCTOID_EXCEPTION"),                                RectangleLength +  " "  +                                RectangleBreadth));        }    }              return iPerimeter.ToString() ;}

Step 10: Compile and Deploy

You are now ready to build and deploy your functoid. Once it is built,
copy the Custom.Biztalk.MathFunctoid.dll to Drive:\Program
Files\Microsoft BizTalk Server 2004\Developer Tools\Mapper Extensions
.

Now, make the DLL available in the GAC, using the following command line
operation:

C:> gacutil /if Copy the Custom.Biztalk.MathFunctoid.dll

Step 11: Adding the functoid to the ToolBox

Open a BizTalk project and go to toolbox, and then right click on the
toolbox. Go to Add/Remove items, select the Functoids tab, and browse to
Custom.Biztalk.MathFunctoid.dll
in the mapper extension folder, and
check it.

You should now see your functoid in the toolbox under the list of
Mathematical functoids (because we set the category as Math, remember?).

Step 12: Take a deep breath!

Congrats, you just finished your first custom BizTalk functoid and I am
sure it wont be your last!

Points of Interest
Testing the functoid

I have included a small map to test the functoid. You can download this
project in the source available for download at the top of this article. It
is titled customFunctoid Map.

Gotcha’s

You cannot insert a bitmap directly into the resource editor, you will
have to use ResEditor to do it. The ResEditor can be found here:
C:\Program Files\Microsoft Visual Studio .NET
2003\SDK\v1.1\Samples\Tutorials\resourcesandlocalization\reseditor
.

Exceptions

You might get an exception that the functoid was not found.

Exception Caught: Functoid not found:  guid({5DE500CC-45BC-454b-A23D-24449899042C})  funcid(6123)

This happens when you GAC the DLL but forget to copy it to the mapper
extension folder.

History

  • Version 1.0 – January 22, 2006.
Advertisements

~ by abhilashms on January 31, 2006.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: