Summary: This article is intended to give you a general idea about what’s functoid in BizTalk. Functoid is no more than a piece of .Net code whichn can perform a complete function.
1. Get Reflector ready before we get started. It can help us to disassemble DLLs and executables, get it from http://www.aisto.com/roeder/dotnet
2. Prepare functoids assembly, once you have BizTalk installed, Microsoft.BizTalk.BaseFunctoids.dll can be found on your machine.
3. Open Microsoft.BizTalk.BaseFunctoids.dll in Reflector and expand this DLL you can find many classes/enumerations such as AssertFunctoid, BaseFunctoid, etc. Take a look at the following screenshot for reference.

4. Every functoid is a class. Just right click on one class you want and select Disassemble. Sorry, I choose BaseFunctoidIDs here, it is an enumeration type. Basically it contains all the functoids coming with BizTalk 2006 R2. (I use BizTalk 2006 R2, I cannot guarantee you can get the same result if you are working with other versions).

BaseFunctoidIDs
1
[ComVisible(true)]
2
public enum BaseFunctoidIDs
3

{
4
Assert = 0x2c3,
5
ConvertAsc = 0x7e,
6
ConvertChr = 0x7f,
7
ConvertHex = 0x80,
8
ConvertOct = 0x81,
9
Count = 0x142,
10
CumulativeAvg = 0x145,
11
CumulativeConcat = 0x148,
12
CumulativeMax = 0x147,
13
CumulativeMin = 0x146,
14
CumulativeSum = 0x144,
15
DateAddDays = 0x7a,
16
DateCurrentDate = 0x7b,
17
DateCurrentDateTime = 0x7d,
18
DateCurrentTime = 0x7c,
19
DBErrorExtract = 0x23f,
20
DBLookup = 0x20c,
21
DBValueExtract = 0x23e,
22
ExistenceLooping = 0x321,
23
Index = 0x143,
24
IsNil = 0x2c2,
25
Iteration = 0x1da,
26
KeyMatch = 800,
27
LogicalAnd = 0x141,
28
LogicalEq = 0x13b,
29
LogicalExistence = 0x2bd,
30
LogicalGt = 0x137,
31
LogicalGte = 0x138,
32
LogicalIsDate = 0x13e,
33
LogicalIsNumeric = 0x13f,
34
LogicalIsString = 0x13d,
35
LogicalLt = 0x139,
36
LogicalLte = 0x13a,
37
LogicalNe = 0x13c,
38
LogicalNot = 0x2c1,
39
LogicalOr = 320,
40
Looping = 0x1a8,
41
MassCopy = 0x322,
42
MathAbs = 0x6f,
43
MathAdd = 0x76,
44
MathDivide = 0x79,
45
MathInt = 0x70,
46
MathMax = 0x71,
47
MathMin = 0x72,
48
MathMod = 0x73,
49
MathMultiply = 120,
50
MathRound = 0x74,
51
MathSqrt = 0x75,
52
MathSubtract = 0x77,
53
NilValue = 0x178,
54
SciArcTan = 130,
55
SciCos = 0x83,
56
SciExp = 0x86,
57
SciExp10 = 0x88,
58
SciLog = 0x87,
59
SciLog10 = 0x89,
60
SciLogn = 0x8b,
61
SciPow = 0x8a,
62
SciSin = 0x84,
63
SciTan = 0x85,
64
Scripter = 260,
65
StringConcatenate = 0x6b,
66
StringFind = 0x65,
67
StringLeft = 0x66,
68
StringLowerCase = 0x67,
69
StringRight = 0x68,
70
StringSize = 0x69,
71
StringSubstring = 0x6a,
72
StringTrimLeft = 0x6c,
73
StringTrimRight = 0x6d,
74
StringUpperCase = 110,
75
TableExtractor = 0x2c0,
76
TableLooping = 0x2bf,
77
ValueMapping = 0x177,
78
ValueMappingFlattening = 0x176,
79
XPath = 0x2be
80
}
81
82
83
5. Now I am choosing BaseFunctoid. It is a little big; every specific functoid will inherit from this abstract class.

BaseFunctoid
1
public abstract class BaseFunctoid
2

{
3
// Fields
4
private Bitmap myBitmap;
5
private Bitmap myBitmap16;
6
private FunctoidCategory myCategory;
7
private string myDescription;
8
private string myExternalAssembly;
9
private string myExternalAssemblyPartialName;
10
private string myExternalAssemblyPath;
11
private string myExternalClassName;
12
private string[] myExternalFunctionNames = new string[3];
13
private bool myHasSideEffects = true;
14
private bool myHasVariableInputs = false;
15
private int myID;
16
private InlineGlobalHelperFunction myInlineGlobalHelperFunctions = InlineGlobalHelperFunction.None;
17
private IList myInputConnectionTypeList = new ArrayList();
18
private Hashtable myMapScriptInfoCache = new Hashtable();
19
private int myMaxParams = -1;
20
private int myMinParams = -1;
21
private string myName;
22
private ConnectionType myOutputConnectionType;
23
private IDictionary myResMgrDict = new Hashtable();
24
private string myResourceAssemblyName;
25
private Hashtable myScriptBuffers = new Hashtable();
26
private Hashtable myScriptGlobalsBuffers = new Hashtable();
27
private Hashtable mySupportedScriptTypes = new Hashtable();
28
private string myTooltip;
29
30
// Methods
31
protected BaseFunctoid()
32
{
33
}
34
35
protected void AddInputConnectionType(ConnectionType connType)
36
{
37
this.myInputConnectionTypeList.Add(connType);
38
}
39
40
public void AddScriptTypeSupport(ScriptType scriptType)
41
{
42
if (!this.mySupportedScriptTypes.ContainsKey(scriptType))
43
{
44
this.mySupportedScriptTypes[scriptType] = true;
45
}
46
this.ClearScriptInfoCache(scriptType);
47
}
48
49
protected string BuildDynamicScriptHeader(string functionName, string returnType, string paramType, int numParams)
50
{
51
StringBuilder builder = new StringBuilder();
52
builder.Append("public ");
53
builder.Append(returnType);
54
builder.Append(" ");
55
builder.Append(functionName);
56
builder.Append("(");
57
for (int i = 0; i < numParams; i++)
58
{
59
if (i > 0)
60
{
61
builder.Append(", ");
62
}
63
builder.Append(paramType);
64
builder.Append(" param");
65
builder.Append(i.ToString(CultureInfo.InvariantCulture));
66
}
67
builder.Append(")\n");
68
return builder.ToString();
69
}
70
71
private void ClearScriptInfoCache(ScriptType scriptType)
72
{
73
if (this.myMapScriptInfoCache.ContainsKey(scriptType))
74
{
75
this.myMapScriptInfoCache.Remove(scriptType);
76
}
77
}
78
79
public static BaseFunctoid CreateScripterClone(BaseFunctoid functoidOrig)
80
{
81
if (functoidOrig == null)
82
{
83
throw new ArgumentNullException("functoidOrig");
84
}
85
BaseFunctoid functoid = new ScripterFunctoid();
86
functoid.myResourceAssemblyName = functoidOrig.myResourceAssemblyName;
87
functoid.myID = functoidOrig.myID;
88
functoid.myName = functoidOrig.myName;
89
functoid.myTooltip = functoidOrig.myTooltip;
90
functoid.myDescription = functoidOrig.myDescription;
91
functoid.myCategory = functoidOrig.myCategory;
92
functoid.myBitmap = functoidOrig.myBitmap;
93
functoid.myBitmap16 = functoidOrig.myBitmap16;
94
functoid.myCategory = functoidOrig.myCategory;
95
functoid.myMinParams = functoidOrig.myMinParams;
96
functoid.myMaxParams = functoidOrig.myMaxParams;
97
functoid.myOutputConnectionType = functoidOrig.myOutputConnectionType;
98
functoid.myInputConnectionTypeList = functoidOrig.myInputConnectionTypeList;
99
functoid.myHasVariableInputs = functoidOrig.myHasVariableInputs;
100
functoid.myResMgrDict = functoidOrig.myResMgrDict;
101
functoid.myInlineGlobalHelperFunctions = functoidOrig.myInlineGlobalHelperFunctions;
102
return functoid;
103
}
104
105
public ScriptType GetBestSupportedScriptType(ArrayList listScriptTypePrecedence)
106
{
107
if (listScriptTypePrecedence != null)
108
{
109
foreach (ScriptTypePrecedenceNode node in listScriptTypePrecedence)
110
{
111
if (((node != null) && node.Enabled) && this.mySupportedScriptTypes.ContainsKey(node.ScriptType))
112
{
113
return node.ScriptType;
114
}
115
}
116
}
117
return ScriptType.None;
118
}
119
120
protected string GetExternalFunctionName(int functionNumber)
121
{
122
if ((functionNumber < 0) || (functionNumber >= this.myExternalFunctionNames.Length))
123
{
124
throw new ArgumentOutOfRangeException("functionNumber", BaseFunctoidsResourceManager.GetResourceString("IDS_INVALID_FUNCTOID_FUNCTION_NUMBER"));
125
}
126
return this.myExternalFunctionNames[functionNumber];
127
}
128
129
public string GetFunctionName(ScriptType scriptType)
130
{
131
return this.GetFunctionName(scriptType, 0);
132
}
133
134
public string GetFunctionName(ScriptType scriptType, int functionNumber)
135
{
136
if (!IsValidScriptType(scriptType))
137
{
138
throw new ArgumentOutOfRangeException("scriptType", BaseFunctoidsResourceManager.GetResourceString("IDS_INVALID_SCRIPT_TYPE"));
139
}
140
if (!this.IsValidFunctionNumber(functionNumber))
141
{
142
throw new ArgumentOutOfRangeException("functionNumber", BaseFunctoidsResourceManager.GetResourceString("IDS_INVALID_FUNCTOID_FUNCTION_NUMBER"));
143
}
144
if (functionNumber == 0)
145
{
146
return this.UpdateScriptInfoCache(scriptType).MethodName;
147
}
148
switch (scriptType)
149
{
150
case ScriptType.ExternalAssembly:
151
return this.GetExternalFunctionName(functionNumber);
152
153
case ScriptType.Xslt:
154
return "";
155
}
156
return this.GetScriptingLanguageFunctionName(scriptType, functionNumber);
157
}
158
159
public static string GetInlineGlobalHelperScriptBuffer(ScriptType scriptType, InlineGlobalHelperFunction functions)
160
{
161
switch (scriptType)
162
{
163
case ScriptType.VbNet:
164
return GetInlineGlobalHelperScriptBufferVbNet(functions);
165
166
case ScriptType.CSharp:
167
return GetInlineGlobalHelperScriptBufferCSharp(functions);
168
169
case ScriptType.JScript:
170
return GetInlineGlobalHelperScriptBufferJScript(functions);
171
}
172
return "";
173
}
174
175
private static string GetInlineGlobalHelperScriptBufferCSharp(InlineGlobalHelperFunction functions)
176
{
177
StringBuilder builder = new StringBuilder();
178
if (InlineGlobalHelperFunction.IsNumeric == (functions & InlineGlobalHelperFunction.IsNumeric))
179
{
180
builder.Append("public bool IsNumeric(string val)\n");
181
builder.Append("{\n");
182
builder.Append("\tif (val == null)\n");
183
builder.Append("\t{\n");
184
builder.Append("\t\treturn false;\n");
185
builder.Append("\t}\n");
186
builder.Append("\tdouble d = 0;\n");
187
builder.Append("\treturn Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);\n");
188
builder.Append("}\n\n");
189
builder.Append("public bool IsNumeric(string val, ref double d)\n");
190
builder.Append("{\n");
191
builder.Append("\tif (val == null)\n");
192
builder.Append("\t{\n");
193
builder.Append("\t\treturn false;\n");
194
builder.Append("\t}\n");
195
builder.Append("\treturn Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);\n");
196
builder.Append("}\n\n");
197
}
198
if (InlineGlobalHelperFunction.IsDate == (functions & InlineGlobalHelperFunction.IsDate))
199
{
200
builder.Append("public bool IsDate(string val)\n");
201
builder.Append("{\n");
202
builder.Append("\tbool retval = true;\n");
203
builder.Append("\ttry\n");
204
builder.Append("\t{\n");
205
builder.Append("\t\tDateTime dt = Convert.ToDateTime(val, System.Globalization.CultureInfo.InvariantCulture);\n");
206
builder.Append("\t}\n");
207
builder.Append("\tcatch (Exception)\n");
208
builder.Append("\t{\n");
209
builder.Append("\t\tretval = false;\n");
210
builder.Append("\t}\n");
211
builder.Append("\treturn retval;\n");
212
builder.Append("}\n\n");
213
}
214
if (InlineGlobalHelperFunction.ValToBool == (functions & InlineGlobalHelperFunction.ValToBool))
215
{
216
builder.Append("public bool ValToBool(string val)\n");
217
builder.Append("{\n");
218
builder.Append("\tif (val != null)\n");
219
builder.Append("\t{\n");
220
builder.Append("\t\tif (string.Compare(val, bool.TrueString, StringComparison.OrdinalIgnoreCase) == 0)\n");
221
builder.Append("\t\t{\n");
222
builder.Append("\t\t\treturn true;\n");
223
builder.Append("\t\t}\n");
224
builder.Append("\t\tif (string.Compare(val, bool.FalseString, StringComparison.OrdinalIgnoreCase) == 0)\n");
225
builder.Append("\t\t{\n");
226
builder.Append("\t\t\treturn false;\n");
227
builder.Append("\t\t}\n");
228
builder.Append("\t\tval = val.Trim();\n");
229
builder.Append("\t\tif (string.Compare(val, bool.TrueString, StringComparison.OrdinalIgnoreCase) == 0)\n");
230
builder.Append("\t\t{\n");
231
builder.Append("\t\t\treturn true;\n");
232
builder.Append("\t\t}\n");
233
builder.Append("\t\tif (string.Compare(val, bool.FalseString, StringComparison.OrdinalIgnoreCase) == 0)\n");
234
builder.Append("\t\t{\n");
235
builder.Append("\t\t\treturn false;\n");
236
builder.Append("\t\t}\n");
237
builder.Append("\t\tdouble d = 0;\n");
238
builder.Append("\t\tif (IsNumeric(val, ref d))\n");
239
builder.Append("\t\t{\n");
240
builder.Append("\t\t\treturn (d > 0);\n");
241
builder.Append("\t\t}\n");
242
builder.Append("\t}\n");
243
builder.Append("\treturn false;\n");
244
builder.Append("}\n\n");
245
}
246
return builder.ToString();
247
}
248
249
private static string GetInlineGlobalHelperScriptBufferJScript(InlineGlobalHelperFunction functions)
250
{
251
return "";
252
}
253
254
private static string GetInlineGlobalHelperScriptBufferVbNet(InlineGlobalHelperFunction functions)
255
{
256
return "";
257
}
258
259
protected virtual string GetInlineScriptBuffer(ScriptType scriptType, int numParams, int functionNumber)
260
{
261
if (this.myScriptBuffers.ContainsKey(scriptType))
262
{
263
string[] strArray = (string[]) this.myScriptBuffers[scriptType];
264
return strArray[functionNumber];
265
}
266
return "";
267
}
268
269
public ConnectionType GetInputConnectionType(int param)
270
{
271
ConnectionType all = ConnectionType.All;
272
if (param < this.myInputConnectionTypeList.Count)
273
{
274
all = (ConnectionType) this.myInputConnectionTypeList[param];
275
}
276
return all;
277
}
278
279
public int GetMaxParams(ScriptType scriptType)
280
{
281
int count = 0;
282
if (this.myMaxParams == -1)
283
{
284
int scriptmin = 0;
285
int scriptmax = 0;
286
if (this.GetMinMaxScriptParams(scriptType, out scriptmin, out scriptmax))
287
{
288
return scriptmax;
289
}
290
if (this.HasVariableInputs)
291
{
292
return 100;
293
}
294
if (this.myInputConnectionTypeList.Count > 0)
295
{
296
count = this.myInputConnectionTypeList.Count;
297
}
298
return count;
299
}
300
return this.myMaxParams;
301
}
302
303
private bool GetMinMaxScriptParams(ScriptType scriptType, out int scriptmin, out int scriptmax)
304
{
305
scriptmin = 0;
306
scriptmax = 0;
307
if (this.mySupportedScriptTypes.Count == 0)
308
{
309
return false;
310
}
311
if ((scriptType != ScriptType.None) && (ScriptType.Xslt != scriptType))
312
{
313
ScriptInfo info = this.UpdateScriptInfoCache(scriptType);
314
scriptmin = info.Min;
315
scriptmax = info.Max;
316
}
317
return true;
318
}
319
320
public int GetMinParams(ScriptType scriptType)
321
{
322
int count = 0;
323
if (this.myMinParams == -1)
324
{
325
int scriptmin = 0;
326
int scriptmax = 0;
327
if (this.GetMinMaxScriptParams(scriptType, out scriptmin, out scriptmax))
328
{
329
return scriptmin;
330
}
331
if (this.myInputConnectionTypeList.Count > 0)
332
{
333
count = this.myInputConnectionTypeList.Count;
334
}
335
return count;
336
}
337
return this.myMinParams;
338
}
339
340
protected ResourceManager GetResourceManager(string resourceAssemblyName)
341
{
342
if (string.IsNullOrEmpty(resourceAssemblyName))
343
{
344
return null;
345
}
346
ResourceManager manager = null;
347
try
348
{
349
manager = (ResourceManager) this.myResMgrDict[resourceAssemblyName];
350
}
351
catch (Exception)
352
{
353
}
354
return manager;
355
}
356
357
public string GetScriptBuffer(ScriptType scriptType)
358
{
359
return this.GetScriptBuffer(scriptType, 0);
360
}
361
362
public string GetScriptBuffer(ScriptType scriptType, int numParams)
363
{
364
return this.GetScriptBuffer(scriptType, numParams, 0);
365
}
366
367
public string GetScriptBuffer(ScriptType scriptType, int numParams, int functionNumber)
368
{
369
return this.GetInlineScriptBuffer(scriptType, numParams, functionNumber);
370
}
371
372
public string GetScriptGlobalBuffer(ScriptType scriptType)
373
{
374
if (this.myScriptGlobalsBuffers.ContainsKey(scriptType))
375
{
376
return (string) this.myScriptGlobalsBuffers[scriptType];
377
}
378
return null;
379
}
380
381
private string GetScriptingLanguageFunctionName(ScriptType scriptType, int functionNumber)
382
{
383
string str;
384
int num;
385
new InlineScriptCompiler().GetMethodInfo(scriptType, this.GetScriptBuffer(scriptType, 0, functionNumber), this.GetScriptGlobalBuffer(scriptType), this.RequiredGlobalHelperFunctions, out str, out num);
386
return str;
387
}
388
389
public static bool IsDate(string val)
390
{
391
DateTime time;
392
if (string.IsNullOrEmpty(val))
393
{
394
return false;
395
}
396
return DateTime.TryParse(val, CultureInfo.InvariantCulture, DateTimeStyles.None, out time);
397
}
398
399
public static bool IsNumeric(string val)
400
{
401
if (string.IsNullOrEmpty(val))
402
{
403
return false;
404
}
405
double result = 0.0;
406
return double.TryParse(val, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out result);
407
}
408
409
public static bool IsNumeric(string val, ref double d)
410
{
411
d = 0.0;
412
if (string.IsNullOrEmpty(val))
413
{
414
return false;
415
}
416
return double.TryParse(val, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out d);
417
}
418
419
public bool IsSupportedScriptType(ScriptType scriptType)
420
{
421
return this.mySupportedScriptTypes.ContainsKey(scriptType);
422
}
423
424
private bool IsValidFunctionNumber(int functionNumber)
425
{
426
int num = 0;
427
int num2 = 0;
428
if (FunctoidCategory.DatabaseLookup == this.Category)
429
{
430
num2 = 1;
431
}
432
else if (FunctoidCategory.Cumulative == this.Category)
433
{
434
num2 = 2;
435
}
436
return ((num <= functionNumber) && (functionNumber <= num2));
437
}
438
439
public static bool IsValidScriptType(ScriptType scriptType)
440
{
441
if ((((scriptType != ScriptType.None) && (ScriptType.ExternalAssembly != scriptType)) && ((ScriptType.Xslt != scriptType) && (ScriptType.XsltCallTemplate != scriptType))) && (((ScriptType.VbNet != scriptType) && (ScriptType.CSharp != scriptType)) && (ScriptType.JScript != scriptType)))
442
{
443
return (ScriptType.JSharp == scriptType);
444
}
445
return true;
446
}
447
448
protected Bitmap LoadBitmap(string resourceAssemblyName, string resourceID)
449
{
450
ResourceManager resourceManager = this.GetResourceManager(resourceAssemblyName);
451
if (resourceManager != null)
452
{
453
return (resourceManager.GetObject(resourceID, Thread.CurrentThread.CurrentUICulture) as Bitmap);
454
}
455
return null;
456
}
457
458
protected string LoadString(string resourceAssemblyName, string resourceID)
459
{
460
ResourceManager resourceManager = this.GetResourceManager(resourceAssemblyName);
461
if (resourceManager != null)
462
{
463
return resourceManager.GetString(resourceID, Thread.CurrentThread.CurrentUICulture);
464
}
465
return null;
466
}
467
468
public void RemoveScriptTypeSupport(ScriptType scriptType)
469
{
470
if (this.mySupportedScriptTypes.ContainsKey(scriptType))
471
{
472
this.mySupportedScriptTypes.Remove(scriptType);
473
}
474
}
475
476
protected void SetBitmap(string resourceID)
477
{
478
this.myBitmap = this.LoadBitmap(this.myResourceAssemblyName, resourceID);
479
try
480
{
481
this.myBitmap16 = this.LoadBitmap(this.myResourceAssemblyName, resourceID + "_16");
482
}
483
catch (Exception)
484
{
485
this.myBitmap16 = this.myBitmap;
486
}
487
}
488
489
protected void SetDescription(string resourceID)
490
{
491
this.Description = this.LoadString(this.myResourceAssemblyName, resourceID);
492
}
493
494
public void SetExternalFunctionName(string assemblyName, string className, string functionName)
495
{
496
this.AddScriptTypeSupport(ScriptType.ExternalAssembly);
497
this.ExternalAssembly = assemblyName;
498
this.ExternalClassName = className;
499
this.myExternalFunctionNames[0] = functionName;
500
}
501
502
public void SetExternalFunctionName(string assemblyPartialName, string assemblyName, string className, string functionName)
503
{
504
this.ExternalAssemblyPartialName = assemblyPartialName;
505
this.SetExternalFunctionName(assemblyName, className, functionName);
506
}
507
508
public void SetExternalFunctionName2(string functionName2)
509
{
510
this.myExternalFunctionNames[1] = functionName2;
511
}
512
513
public void SetExternalFunctionName3(string functionName3)
514
{
515
this.myExternalFunctionNames[2] = functionName3;
516
}
517
518
public void SetExternalFunctionNameWithAsmPath(string assemblyName, string assemblyPath, string className, string functionName)
519
{
520
this.AddScriptTypeSupport(ScriptType.ExternalAssembly);
521
this.ExternalAssembly = assemblyName;
522
this.ExternalAssemblyPath = assemblyPath;
523
this.ExternalClassName = className;
524
this.myExternalFunctionNames[0] = functionName;
525
}
526
527
public void SetMaxParams(int maxParams)
528
{
529
this.myMaxParams = maxParams;
530
}
531
532
public void SetMinParams(int minParams)
533
{
534
this.myMinParams = minParams;
535
}
536
537
protected void SetName(string resourceID)
538
{
539
this.Name = this.LoadString(this.myResourceAssemblyName, resourceID);
540
}
541
542
public void SetScriptBuffer(ScriptType scriptType, string scriptBuffer)
543
{
544
this.SetScriptBuffer(scriptType, scriptBuffer, 0);
545
}
546
547
public void SetScriptBuffer(ScriptType scriptType, string scriptBuffer, int functionNumber)
548
{
549
string[] strArray = null;
550
if (this.myScriptBuffers.ContainsKey(scriptType))
551
{
552
strArray = (string[]) this.myScriptBuffers[scriptType];
553
}
554
else
555
{
556
strArray = new string[3];
557
this.myScriptBuffers[scriptType] = strArray;
558
}
559
strArray[functionNumber] = scriptBuffer;
560
this.AddScriptTypeSupport(scriptType);
561
}
562
563
public void SetScriptGlobalBuffer(ScriptType scriptType, string scriptGlobalsBuffer)
564
{
565
if (this.myScriptGlobalsBuffers.ContainsKey(scriptType))
566
{
567
this.myScriptGlobalsBuffers.Remove(scriptType);
568
}
569
this.myScriptGlobalsBuffers.Add(scriptType, scriptGlobalsBuffer);
570
}
571
572
protected void SetTooltip(string resourceID)
573
{
574
this.Tooltip = this.LoadString(this.myResourceAssemblyName, resourceID);
575
}
576
577
protected void SetupResourceAssembly(string resAsmName, Assembly resAssembly)
578
{
579
this.myResourceAssemblyName = resAsmName;
580
ResourceManager manager = null;
581
try
582
{
583
manager = (ResourceManager) this.myResMgrDict[this.myResourceAssemblyName];
584
}
585
catch (Exception)
586
{
587
}
588
if (manager == null)
589
{
590
try
591
{
592
manager = new ResourceManager(this.myResourceAssemblyName, resAssembly);
593
manager.GetObject("__xx__xx__xx__xx__", Thread.CurrentThread.CurrentUICulture);
594
}
595
catch (Exception)
596
{
597
manager = null;
598
}
599
if (manager != null)
600
{
601
this.myResMgrDict[this.myResourceAssemblyName] = manager;
602
}
603
}
604
}
605
606
private ScriptInfo UpdateScriptInfoCache(ScriptType scriptType)
607
{
608
int min = 0;
609
int max = 0;
610
string methodName = "";
611
ScriptInfo info = null;
612
if (this.myMapScriptInfoCache.ContainsKey(scriptType))
613
{
614
return (ScriptInfo) this.myMapScriptInfoCache[scriptType];
615
}
616
if (ScriptType.ExternalAssembly == scriptType)
617
{
618
methodName = this.GetExternalFunctionName(0);
619
if (this.myMinParams != -1)
620
{
621
min = this.myMinParams;
622
}
623
else if (this.myInputConnectionTypeList.Count > 0)
624
{
625
min = this.myInputConnectionTypeList.Count;
626
}
627
if (this.myMaxParams != -1)
628
{
629
max = this.myMaxParams;
630
}
631
else if (this.HasVariableInputs)
632
{
633
max = 100;
634
}
635
else
636
{
637
max = (this.myInputConnectionTypeList.Count > 0) ? this.myInputConnectionTypeList.Count : 100;
638
}
639
}
640
else if (((ScriptType.CSharp == scriptType) || (ScriptType.VbNet == scriptType)) || (((ScriptType.JScript == scriptType) || (ScriptType.JSharp == scriptType)) || (ScriptType.XsltCallTemplate == scriptType)))
641
{
642
int num3;
643
new InlineScriptCompiler().GetMethodInfo(scriptType, this.GetScriptBuffer(scriptType), this.GetScriptGlobalBuffer(scriptType), this.RequiredGlobalHelperFunctions, out methodName, out num3);
644
min = num3;
645
max = num3;
646
if ((max == 0) && this.HasVariableInputs)
647
{
648
max = 100;
649
}
650
}
651
else
652
{
653
min = 0;
654
max = 0;
655
methodName = "";
656
}
657
info = new ScriptInfo(min, max, methodName);
658
this.myMapScriptInfoCache[scriptType] = info;
659
return info;
660
}
661
662
// Properties
663
public FunctoidCategory Category
664
{
665
get
666
{
667
return this.myCategory;
668
}
669
set
670
{
671
this.myCategory = value;
672
}
673
}
674
675
public string Description
676
{
677
get
678
{
679
return this.myDescription;
680
}
681
set
682
{
683
this.myDescription = value;
684
}
685
}
686
687
public string ExternalAssembly
688
{
689
get
690
{
691
return this.myExternalAssembly;
692
}
693
set
694
{
695
this.myExternalAssembly = value;
696
}
697
}
698
699
public string ExternalAssemblyPartialName
700
{
701
get
702
{
703
return this.myExternalAssemblyPartialName;
704
}
705
set
706
{
707
this.myExternalAssemblyPartialName = value;
708
}
709
}
710
711
public string ExternalAssemblyPath
712
{
713
get
714
{
715
return this.myExternalAssemblyPath;
716
}
717
set
718
{
719
this.myExternalAssemblyPath = value;
720
}
721
}
722
723
public string ExternalClassName
724
{
725
get
726
{
727
return this.myExternalClassName;
728
}
729
set
730
{
731
this.myExternalClassName = value;
732
}
733
}
734
735
public bool HasSideEffects
736
{
737
get
738
{
739
return this.myHasSideEffects;
740
}
741
set
742
{
743
this.myHasSideEffects = value;
744
}
745
}
746
747
public bool HasVariableInputs
748
{
749
get
750
{
751
return this.myHasVariableInputs;
752
}
753
set
754
{
755
this.myHasVariableInputs = value;
756
}
757
}
758
759
public int ID
760
{
761
get
762
{
763
return this.myID;
764
}
765
set
766
{
767
this.myID = value;
768
}
769
}
770
771
public Bitmap Image
772
{
773
get
774
{
775
return this.myBitmap;
776
}
777
}
778
779
public Bitmap Image16
780
{
781
get
782
{
783
return this.myBitmap16;
784
}
785
}
786
787
public string Name
788
{
789
get
790
{
791
return this.myName;
792
}
793
set
794
{
795
this.myName = value;
796
}
797
}
798
799
public ConnectionType OutputConnectionType
800
{
801
get
802
{
803
return this.myOutputConnectionType;
804
}
805
set
806
{
807
this.myOutputConnectionType = value;
808
}
809
}
810
811
public InlineGlobalHelperFunction RequiredGlobalHelperFunctions
812
{
813
get
814
{
815
return this.myInlineGlobalHelperFunctions;
816
}
817
set
818
{
819
this.myInlineGlobalHelperFunctions = value;
820
}
821
}
822
823
public string Tooltip
824
{
825
get
826
{
827
return this.myTooltip;
828
}
829
set
830
{
831
this.myTooltip = value;
832
}
833
}
834
}
835
836
837
Collapse Methods
838
839
6. Not every property/ function we should pay attention to, we will talk about that in another session.
7. Now let’s take a look at StringLeft functoid. Pay special attention to GetCSharpBuffer method, it uses StringBuilder to create a c# function like this:

StringLeft
1
public string StringLeft(string str, string count)
2

{
3
string retval = "";
4
double d = 0;
5
if (str != null && IsNumeric(count, ref d))
6
{
7
int i = (int) d;
8
if (i > 0)
9
{
10
if (i <= str.Length)
11
{
12
retval = str.Substring(0, i);
13
}
14
else
15
{
16
retval = str;
17
}
18
}
19
}
20
return retval;
21
}
This function is gonna be used in physical map.
8. Create a map to use this functoid.

Right click on the map file (SourcetoTarget.btm) and select Validate map。Please remember, you can get the actual xsl file which will do the transform. From the output window the automatically generated xsl file can be found, open it. In this xsl file you can clearly find the StringLeft function mentioned above and its referenced function(s), IsNumeric in this case.

The idea is when a functoid is put onto the surface of map, it will generate a function in xsl file, xsl can call this code at run time to do transfrom.