自定义内联 functoid 通过将实现代码直接复制到映射中,而不是通过引用程序集、类和方法名称(如自定义引用的 functoid)来提供功能。
生成内联脚本
可通过两种方法提供脚本以包含在地图中。 根据自定义 functoid 是否支持可变数量的参数,从以下方法中进行选择:
当您的自定义 functoid 接受可变数量的输入参数,并且您已将 HasVariableInputs 属性设置为
true
时,请重写 GetInlineScriptBuffer。 例如,如果要连接可变数量的字符串或查找一组值中的最大值,请使用此方法。当不需要支持可变数量的输入参数时,请使用 SetScriptBuffer 。 你仍然可以使用可选参数,但参数总数是固定的。
这两种方法需要不同的实现。
使用 SetScriptBuffer 提供内联代码
将自定义 functoid 配置为使用内联脚本:
使用 Microsoft.BizTalk.BaseFunctoids.ScriptType 调用 AddScriptTypeSupport 以启用内联代码并设置支持的脚本类型。
调用 SetScriptBuffer 以设置要用于自定义 functoid 的代码。 你需使用
functionNumber
参数三次调用此函数来处理自定义累积 functoid,另需调用一次来处理自定义非累积 functoid。使用 SetScriptGlobalBuffer 声明内联代码使用的任何全局变量。
使用 RequiredGlobalHelperFunctions 指示自定义内联 functoid 所需的帮助程序函数。
可以使用 StringBuilder 或常量生成脚本。 编写脚本代码的一种方法是先编写自定义引用的 functoid,在消除所有 bug 后,通过将函数复制到字符串常量,将其转换为内联。
使用 GetInlineScriptBuffer 来提供内联代码
如果自定义内联 functoid 支持可变数量的参数,你将替代 GetInlineScriptBuffer。 将自定义 functoid 配置为使用内联脚本:
在构造函数中,通过将 HasVariableInputs 设置为
true
来声明自定义 functoid 具有变量输入。在构造函数中,使用 Microsoft.BizTalk.BaseFunctoids.ScriptType 调用 AddScriptTypeSupport 以启用内联代码并设置支持的脚本类型。
重写 GetInlineScriptBuffer 以构造并返回在地图中用于自定义 functoid 的代码。 通过检查
scriptType
和numParams
,使用参数来生成正确的代码。 最终参数functionNumber
应为 0。 这是因为累积函数具有固定数量的输入,并且不使用此机制。使用 SetScriptGlobalBuffer 声明内联代码使用的全局变量。
使用 RequiredGlobalHelperFunctions 来指示自定义内联功能节点所需的辅助函数。
以下代码片段生成一个 C# 函数,它具有传入的参数数量(由
numParams
表示),但没有函数体。 若要使用此代码片段,请将示例复制到解决方案,并添加代码以使用参数执行某些作并返回值。
// Override GetInlineScriptBuffer
protected override string GetInlineScriptBuffer(ScriptType scriptType, int numParams, int functionNumber)
{
// Is this one of the supported script types?
if(ScriptType.CSharp == scriptType)
{
// Assume functionNumber == 0
StringBuilder builder = new StringBuilder();
// Function declaration
builder.Append("public string MyFunction("
// Declare parameters using numParams
for(int i=0; i<numParams; i++)
{
// Separate params with a comma
if(i > 0)
builder.Append(", ");
// Declare parameters, param0 to paramNUMPARAM
builder.Append("string param" + i.ToString());
}
builder.Append(")\n");
// Function body; process params as needed
builder.Append("{\n");
builder.Append("}\n");
// Return script
return builder.ToString();
}
// scriptType is unsupported
return string.Empty;
}
测试内联脚本
在任何开发工作中,测试都是一个重要考虑因素。 自定义内联功能点可能很难测试。 若要简化该过程,请使用以下一种或两种技术:
检查使用自定义内联功能体的地图的 XSLT。
验证使用自定义内联功能单元的映射的输入和输出。
检查使用自定义内联功能构件的地图的 XSLT
此方法通常显示逻辑或微妙的语法问题。 它还有助于了解地图中发生的情况。
要查看地图的 XSLT,请执行以下操作:
在 Visual Studio BizTalk 项目中,单击 “解决方案资源管理器 ”选项卡,右键单击使用自定义内联 functoid 的映射,然后单击“ 验证映射”。
滚动“输出”窗口以查找 XSLT 文件的 URL。 按 Ctrl 并单击 URL 以查看文件。
注释
请记住,对 XSLT 文件所做的任何更改都不会反映在自定义 functoid 中。
测试使用自定义内联功能元件进行映射
这将测试映射和自定义内联函数体(functoid)是否按预期工作。
要测试地图:
在 Visual Studio BizTalk 项目中,单击 “解决方案资源管理器”选项卡,右键单击使用自定义内联 functoid 的映射,然后单击“测试映射”。
滚动“输出”窗口以查找输出文件的 URL。 按 Ctrl 并单击 URL 以查看文件。
可以检查输入和输出值,以验证映射是否按预期方式运行。
示例:
以下示例说明如何创建一个自定义内联函数体,以连接两个字符串。 它依赖于包含三个字符串资源和 16x16 像素位图资源的资源文件。
using System;
using Microsoft.BizTalk.BaseFunctoids;
using System.Reflection;
using System.Text;
namespace Microsoft.Samples.BizTalk.CustomFunctoid
{
/// <summary>
/// Performs a string concatenation using inline code.
/// </summary>
public class CustomStringConcatFunctoid : BaseFunctoid
{
public CustomStringConcatFunctoid()
: base()
{
//ID for this functoid
this.ID = 6001;
// Resource assembly must be ProjectName.ResourceName if building with VS.Net
SetupResourceAssembly("Microsoft.Samples.BizTalk.CustomFunctoid.CustomFunctoidResources", Assembly.GetExecutingAssembly());
// Pass the resource ID names for functoid name, tooltip
// description and the 16x16 bitmap for the Map palette
SetName("IDS_CUSTOMSTRINGCONCATFUNCTOID_NAME");
SetTooltip("IDS_CUSTOMSTRINGCONCATFUNCTOID_TOOLTIP");
SetDescription("IDS_CUSTOMSTRINGCONCATFUNCTOID_DESCRIPTION");
SetBitmap("IDB_CUSTOMSTRINGCONCATFUNCTOID_BITMAP");
// Put this string handling function under the String
// Functoid tab in the Visual Studio toolbox for functoids
this.Category = FunctoidCategory.String;
// 2 required parameters, no optional parameters
this.SetMinParams(2);
this.SetMaxParams(2);
// Functoid accepts two inputs
AddInputConnectionType(ConnectionType.AllExceptRecord);
AddInputConnectionType(ConnectionType.AllExceptRecord);
// Set the output connection type
this.OutputConnectionType = ConnectionType.AllExceptRecord;
// Declare support for CSharp inline function and
// pass the method implementation to the buffer
AddScriptTypeSupport(ScriptType.CSharp);
SetScriptBuffer(ScriptType.CSharp, GetCSharpBuffer());
}
private string GetCSharpBuffer()
{
StringBuilder builder = new StringBuilder();
builder.Append("public string ConCatStrings(string val1, string val2)\n");
builder.Append("{\n");
builder.Append(" return val2+val1;\n");
builder.Append("}\n");
return builder.ToString();
}
}
}