1. Implementing Custom Business Rule Functions
This section targets developers creating custom Business Rule functions.
Scope
- Applies to built‑in and plugin‑provided functions
- Not intended for end‑user script authors
2. Required Interface and Runtime Expectations
Custom functions must implement IUnicontaBusinessRuleFunction and:
- Be non‑abstract
- Not be sealed
- Have a public parameterless constructor
Required Members
- Name (string)Visible function name (must be unique)
- Evaluate(object[] operands)
- Must be exception‑safe
- Must tolerate null and invalid operands
- GetResultType(Type[] operands)Used for expression engine type inference
- RuleArgs (BusinessRuleArgs)Runtime context injected by Uniconta
- MinOperandCount / MaxOperandCountOperand metadata for validation
- Category (BusinessRuleFunctionCategory)
- Description (string)
- IsValidOperandCount(int count)
- IsValidOperandType(int index, int operandCount, Type type)
Functions are auto‑discovered when the type is assignable to IUnicontaBusinessRuleFunction.
3. Naming Constraints
- Null or empty names prevent function metadata tracking
- Duplicate names may overwrite existing entries (last write wins)
- Always keep function names unique
4. How RuleArgs Is Populated
Before evaluation, the runtime populates BusinessRuleArgs with:
- Current page
- API instance
- ExtraArguments
- Current DataObject
Accessible properties include:
- Api
- FocussedRow
- CurrentRow
- DataObject
- ExtraArguments
- Vars(shared variable store)
Guidance
- Always null‑check RuleArgs and nested properties
- Expect different shapes depending on trigger context
5. Recommended Implementation Pattern
- Start from BusinessRuleFunctionBasewhen possible
- Set a unique Name
- Parse operands defensively
- Implement GetResultType accurately
- Define coherent operand limits and validators
- Provide meaningful Description / Documentation
Test with:
- Empty operands
- Null operands
- Incorrect types
- Valid types
- Trigger contexts with and without DataObject
6. Pre‑Release Checklist
☐ Public parameterless constructor exists ☐ Name is non‑empty and unique ☐ Evaluate handles nulls and type mismatches safely ☐ GetResultType matches actual return type ☐ Operand limits and validators are consistent ☐ RuleArgs usage is null‑safe and not persisted ☐ Documentation is meaningful to end users