Extending Inaport – Adding Your own Functions

Inaport 7.3 gives you the ability to extend the expression editor by adding your own functions. These functions become available at any point where you can write an expression in Inaport. Some ways this has been used:
- call out to an external web service to get current pricing for commodity products being imported into CRM
- implement specialized parsing of a sales order line
- call out to external database to do conditional updates.
Implementing a new functions is straightforward. You create a DLL in any .NET compatible language, and drop it into the Inaport install directory. Inaport will find the DLL on start up and make the functions in it visible in the Expression Editor.
InaPlex can supply a Visual Studio project with a sample function already implemented, which you can use as a base. The rest of this post will walk through the sample project.
Quick Start
Download and install the demonstration project to use as reference.
- Create Visual Studio project, and add a reference to IPExtensionManager.dll (found in the Inaport install directory)
- Create a new class for each function, extending IPFunctionBase. See sample project for setup.
- Create a single class extending IPExtensionBase. This class loads your functions into the Inaport environment.
- Save the project as a DLL in the Inaport directory. Name *must* start with “IPex”.
- Restart Inaport. Your functions should now be visible in the Inaport expression editor.
Environment
To create your DLL, you need to add a reference to IPExtensionManager.dll, which is installed in the Inaport install directory. This DLL has two classes:
- IPExtensionBase – you extend this to create the base management for your DLL.
- IPFunctionBase – each function you create is its own class. You extend this class to provide functionality and context
These base classes provide the mechanisms for:
- Inaport to find your functions and import them into the Expression Editor environment
- Inaport to call your functions at run time and pass parameters and environment context to them
- Means for you to access logging and exception handling
IPExtensionBase
Extend IPExtensionBase to allow Inaport to load your functions into the Inaport environment. This class also provides access to the debug logging mechanisms for Inaport. The functions provide by IPExtensionBase are:
/// You override this function - Inaport will call at run time for you to initialize and load your functions public virtual void LoadFunctions(); /// Call the following function from your LoadFunctions() implementation for each custom function you want to load protected void AddFunction(IPFunctionBase func);
Here is how your extension class may look:
/// /// Default constructor. You can add required constructor code here. /// public IPExtensionDemo() { // example of using the debug logger DebugLog.Info("My extension is being created"); } /// /// Inaport will call the LoadFunctions() method after the assembly is loaded. /// Your implementation should call AddFunction() for each function you want to add /// to the Inaport Expression Editor. /// public override void LoadFunctions() { AddFunction(new IP_DemoFunction()); AddFunction(new MySecondFunction()); }
Implementing a function
Each function you implement is a class that extends IPFunctionBase. The base class provides all the machinery required for Inaport to recognize your function, add it to the expression editor, and call it correctly with parameters.
Your class will consist of two parts:
- the constructor, which initializes two members: Name and FuncDescriptor.
- an override of the method Evaluate(), which contains the code you want to actually execute when the function is called.
Function constructor
The constructor will look like this:
public IP_DemoFunction() { Name = "IP_DemoFunction("; // name of the function. YES it does need the "(" at the end. FuncDescriptor = new IPFuncDescriptor( "Produce a string showing the argument count and the value of each parameter", // this is the function description "IP_DemoFunction(#field1, \"Test string\")", // this is the example new string[] { "IP_Extensions" }, // this is the category or categories the function will appear under new IPFuncParamDesc[] { // these are the parameter descriptions new IPFuncParamDesc("param1", "description of Parameter 1", "string", false), new IPFuncParamDesc("param2", "description of Parameter 2", "string", false), new IPFuncParamDesc("RETURN", "String showing the argument count and value of each parameter", "string", true) } ); }
The first line sets the Name of the function – this is how you will call it from an Inaport expression.
IPFuncDescriptor() is a type that holds all the information that will appear with your function in the expression editor:
- the description
- the example
- the set of parameters
The Evaluate method
Finally, the evaluate method is where you actually implement your functionality.
Inaport will pass all your parameters on a Stack object. There is no type checking or parameter count checking – it is your responsibility to pull the parameters off the stack in the correct order. The first argument you pop will be an integer count of the number of parameters on the stack; this means that you can implement functions that take variable numbers of parameters.
The IPFunctionBase class provides some utility functions to pop parameters off the stack:
- popInt(stack) – return an int
- popDbl(stack) – return a double
- popStr(stack) – return a string
- popBool(stack) – return a boolean(true or false) value
- popDate(stack) – return a DateTime value.
- popObj(stack) – return the value off the stack as an object. It is then your responsibility to safely cast it to the required data type.
The functions use the System.Convert.ToXXX() methods to convert the object on the stack to the required data type, and will throw ArgumentNullException if the parameter is null or DBNUll, and ArguementException if the parameter cannot be converted to the requested data type.
The example implementation looks like this:
public override object Evaluate(Stack stack) { string res; int argCount = popInt(stack); res = "Arg count: " + argCount; var myLogger = GetLogger("IPDemoLogger"); myLogger.Info("IP_DemoFunction.Evaluate called with " + argCount + " arguments"); for (int i = argCount; i > 0; i--) { res += System.Environment.NewLine + "Parameter: " + i + " Value: " + popObj(stack).ToString(); } return res; }
The first line of code pops the argument count from the stack; this is required, even if you do not use it.
The second and third lines create a debug logger, using the Inaport logging infrastructure; this is not required in your code, but can be useful for debugging. The logger is then used to print out some information. This is discussed further below.
Finally, the for() loop pops each of the other parameters off the stack and concatenates them into a string, which is then returned as the result of the expression.
Debug Logging
Inaport provides a powerful and flexible logging infrastructure, using the Apache log4net framework.
IPExtensionBase provides a default debug logger, called DebugLog, as a property of the base class. To use it, simply use the Debug() method on it:
DebugLog.Debug(“My debug stuff: ” + someVar.ToString())
Debug logging is turned on through the Inaport user interface: Tools – Start Debug Logging.
If you want more flexibility, you can use the GetLogger() method to get a logger you have configured in the LoggingConfig.xml file which is in the Inaport install directory. See the log4net documentation for more details.
Conclusion
If you use the Inaport extensiblity to create interesting applications, let us know and we will list them here.
Inaport, from InaPlex, delivers CRM integration and data migration solutions for leading CRM systems including Salesforce, Microsoft Dynamics CRM, Sage CRM, Infor CRM (previously Saleslogix), Goldmine and ACT. It has a range of connectors and maps for quick results, and its straightforward approach provides a wealth of powerful functions. To learn more please book a free webinar, download a free 30 day evaluation license, or visit the InaPlex website.