/// <summary> /// Adds an individual formula function /// </summary> /// <param name="functionCall">A delegate pointing to the method you wish to add</param> /// <remarks> /// This function lets you add an individual formula function by specifying a delegate pointing to it. The method that /// the delegate refers to must be tagged with the appropriate /// <see cref="T:ciloci.FormulaEngine.FormulaFunctionAttribute">attribute</see>. /// </remarks> /// <exception cref="T:System.ArgumentException"> /// The method that the delegate points to is not tagged with the required /// attribute /// </exception> /// <exception cref="T:System.InvalidOperationException"> /// The function was called while formulas are defined in the formula engine /// <para>A function with the same name is already defined</para> /// </exception> public void AddFunction(FormulaFunctionCall functionCall) { FormulaEngine.ValidateNonNull(functionCall, "functionCall"); ValidateEngineStateForChangingFunctions(); var attr = (FormulaFunctionAttribute) Attribute.GetCustomAttribute(functionCall.Method, typeof(FormulaFunctionAttribute)); if (attr == null) { throw new ArgumentException("The function does not have a FormulaFunctionAttribute defined on it"); } var info = new FunctionInfo(functionCall, attr); AddFunctionInternal(info); }
public FunctionInfo(FormulaFunctionCall target, FormulaFunctionAttribute attr) { FunctionTarget = target; FunctionAttribute = attr; string targetName = target.Method.Name; if (attr.Names != null && attr.Names.Length > 0) { int addlNamesLen = attr.Names.Length; Names = new string[addlNamesLen + 1]; Array.Copy(attr.Names, 0, Names, 1, addlNamesLen); } else { Names = new string[1]; } Names[0] = targetName; Volatile = attr.IsVolatile; }
/// <summary> /// Go through all methods of a type and try to add them as formula functions /// </summary> private void AddFormulaMethods(Type targetType, IDelegateCreator creator) { ValidateEngineStateForChangingFunctions(); BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Public | creator.Flags; foreach (MethodInfo mi in targetType.GetMethods(flags)) { var attr = (FormulaFunctionAttribute)Attribute.GetCustomAttribute(mi, typeof(FormulaFunctionAttribute)); if (attr != null) { FormulaFunctionCall d = creator.CreateDelegate(mi.Name); if (d == null) { throw new ArgumentException(String.Format("The method {0} is marked as a formula function but does not have the correct signature", mi.Name)); } var info = new FunctionInfo(d, attr); AddFunctionInternal(info); } } }