ExcelIntegration.RegisterUnhandledExceptionHandler(ex => "!!! ERROR: " + ex.ToString());
// Since the .dna file has ExplicitExports="true", these explicit registrations are the only ones - there is no default processing
ExcelRegistration.GetExcelFunctions().ProcessMapArrayFunctions(conversionConfig);
ExcelRegistration.GetExcelFunctions().ProcessParameterConversions(conversionConfig);
ExcelRegistration.GetExcelFunctions().ProcessAsyncRegistrations(nativeAsyncIfAvailable: false);
ExcelRegistration.GetExcelFunctions().ProcessParameterConversions(postAsyncReturnConfig);
ExcelRegistration.GetExcelFunctions().ProcessFunctionExecutionHandlers(functionHandlerConfig);
static ParameterConversionConfiguration GetParameterConversionConfig()
{
// NOTE: The parameter conversion list is processed once per parameter.
// Parameter conversions will apply from most inside, to most outside.
// So to apply a conversion chain like
// string -> Type1 -> Type2
// we need to register in the (reverse) order
// Type1 -> Type2
// string -> Type1
//
// (If the registration were in the order
// string -> Type1
// Type1 -> Type2
// the parameter (starting as Type2) would not match the first conversion,
// then the second conversion (Type1 -> Type2) would be applied, and no more,
// leaving the parameter having Type1 (and probably not eligible for Excel registration.)
//
//
// Return conversions are also applied from most inside to most outside.
// So to apply a return conversion chain like
// Type1 -> Type2 -> string
// we need to register the ReturnConversions as
// Type1 -> Type2
// Type2 -> string
//
var paramConversionConfig = new ParameterConversionConfiguration()
// Register the Standard Parameter Conversions (with the optional switch on how to treat references to empty cells)
.AddParameterConversion(ParameterConversions.GetOptionalConversion(treatEmptyAsMissing: true))
// Register some type conversions (note the ordering discussed above)
// .AddParameterConversion((TestType1 value) => new TestType2(value))
//.AddParameterConversion((string value) => new TestType1(value))
// This is a conversion applied to the return value of the function
//.AddReturnConversion((TestType1 value) => value.ToString())
.AddReturnConversion((Complex value) => new double[2] { value.Real, value.Imaginary })
// .AddParameterConversion((string value) => convert2(convert1(value)));
// This parameter conversion adds support for string[] parameters (by accepting object[] instead).
// It uses the TypeConversion utility class defined in ExcelDna.Registration to get an object->string
// conversion that is consist with Excel (in this case, Excel is called to do the conversion).
.AddParameterConversion((object[] inputs) => inputs.Select(TypeConversion.ConvertToString).ToArray())
// This is a pair of very generic conversions for Enum types
.AddReturnConversion((Enum value) => value.ToString(), handleSubTypes: true)
.AddParameterConversion(ParameterConversions.GetEnumStringConversion())
.AddParameterConversion((object[] input) => new Complex(TypeConversion.ConvertToDouble(input[0]), TypeConversion.ConvertToDouble(input[1])))
.AddNullableConversion(treatEmptyAsMissing: true, treatNAErrorAsMissing: true);
return paramConversionConfig;
}