Open TheCakeMonster opened 1 year ago
It seems like you're bumping up against the original design of NCalc here. NCalc doesn't really allow you to register custom functions. It allows you to register a custom event handler any time a function is evaluated. All registered event handlers will be invoked and can potentially set Result, yielding the behavior you've described. I believe .net event handlers are called in the order they were added so if your internal library adds itself after PanoramicData.NCalcExtensions I think it should set Result last and thus win, but you'll be doing extra work.
Some options that wouldn't require NCalc changes:
public class InternalExtendedExpression : ExtendedExpression {
protected override void Extend(string functionName, FunctionArgs functionArgs) {
switch(functionName) {
case "collision":
functionArgs.Result = "correct";
return;
}
return base.Extend(functionName, functionArgs);
}
}
TLDR; Adding custom functions to published NCalc function libraries, or NCalc itself, can cause unexpected breaking changes to the way an expression is evaluated if the names of the functions clash. It is unexpected that the addition of new functions would be a breaking change, especially as it does not generate any error message, either at compile time or runtime.
Detailed Explanation We publish and use an open source library of functions to make NCalc even more useful, namely PanoramicData.NCalcExtensions. PanoramicData.NCalcExtensions extends NCalc by inheriting from the Expression type and adding an event handler to the EvaluateFunction event handler.
One of our internal systems provides even more, system-specific extensions by inheriting from the derived ExtendedExpression class from PanoramicData.NCalcExtensions - adding a third set/layer of functions. Within this system we can therefore evaluate expressions containing functions from NCalc, from PanoramicData.NCalcExtensions and from our system itself.
Recently, a new function was added to PanoramicData.NCalcExtensions with the same name as one of the custom functions in our own system. Suddenly, the function in the PanoramicData.NCalcExtensions library is being used in preference to the one in our own system, breaking our consuming system's functionality. It turns out that adding new functions to a shared, custom functions library can be a breaking change, and this was unexpected.
Possible changes to resolve the issue (not exclusive):
Fully resolving this issue using my preferred solution (change 1 above) is probably a breaking change, as I think the behaviour can only be changed by replacing the EvaluateFunction event handler with another mechanism that has the ability to guarantee - and control - the order of evaluating which function to use.
I am aware that this library is not actively maintained, but I thought I would post my discovery so that other people were aware of the problem - this might help other people track down an issue they have. Furthermore, should any changes be made to NCalc in the future, this change can be considered as part of those efforts.
Disclaimer: I work for Panoramic Data. I don't see a conflict of interest because of this, but I mention it in the spirit of full disclosure.