Skip to content

Commit 37c47bd

Browse files
authored
Merge branch 'master' into NativeAOT
2 parents 76f27c7 + 3dbc995 commit 37c47bd

File tree

14 files changed

+250
-51
lines changed

14 files changed

+250
-51
lines changed

Source/ExcelDna.Integration/AssemblyLoader.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ public static void ProcessAssemblies(
3636
List<Type> rtdServerTypes,
3737
List<ExcelComClassType> comClassTypes)
3838
{
39-
bool loadRibbons = true;
40-
4139
foreach (ExportedAssembly assembly in assemblies)
4240
{
4341
int initialObjectsCount = methods.Count +

Source/ExcelDna.Integration/DnaLibrary.cs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -257,16 +257,10 @@ internal List<ExportedAssembly> GetAssemblies(string pathResolveRoot)
257257
[XmlIgnore]
258258
private List<MethodInfo> _methods = new List<MethodInfo>();
259259
[XmlIgnore]
260-
List<ExtendedRegistration.ExcelParameterConversion> _excelParameterConversions = new List<ExtendedRegistration.ExcelParameterConversion>();
261-
[XmlIgnore]
262-
List<ExtendedRegistration.ExcelReturnConversion> _excelReturnConversions = new List<ExtendedRegistration.ExcelReturnConversion>();
260+
private ExtendedRegistration.Registration.Configuration _extendedRegistrationConfiguration;
263261
[XmlIgnore]
264262
private List<Registration.ExcelFunctionRegistration> _excelFunctionsExtendedRegistration = new List<Registration.ExcelFunctionRegistration>();
265263
[XmlIgnore]
266-
private List<Registration.FunctionExecutionHandlerSelector> _excelFunctionExecutionHandlerSelectors = new List<Registration.FunctionExecutionHandlerSelector>();
267-
[XmlIgnore]
268-
private List<ExtendedRegistration.ExcelFunctionProcessor> _excelFunctionProcessors = new List<ExtendedRegistration.ExcelFunctionProcessor>();
269-
[XmlIgnore]
270264
private List<ExportedAssembly> _exportedAssemblies;
271265

272266
// The idea is that Initialize compiles, loads and sorts out the assemblies,
@@ -283,7 +277,14 @@ internal void Initialize()
283277

284278
// Recursively get assemblies down .dna tree.
285279
_exportedAssemblies = GetAssemblies(dnaResolveRoot);
286-
AssemblyLoader.ProcessAssemblies(_exportedAssemblies, _methods, _excelParameterConversions, _excelReturnConversions, _excelFunctionProcessors, _excelFunctionsExtendedRegistration, _excelFunctionExecutionHandlerSelectors, _addIns, rtdServerTypes, comClassTypes);
280+
281+
var excelParameterConversions = new List<ExtendedRegistration.ExcelParameterConversion>();
282+
var excelReturnConversions = new List<ExtendedRegistration.ExcelReturnConversion>();
283+
var excelFunctionExecutionHandlerSelectors = new List<Registration.FunctionExecutionHandlerSelector>();
284+
var excelFunctionProcessors = new List<ExtendedRegistration.ExcelFunctionProcessor>();
285+
AssemblyLoader.ProcessAssemblies(_exportedAssemblies, _methods, excelParameterConversions, excelReturnConversions, excelFunctionProcessors, _excelFunctionsExtendedRegistration, excelFunctionExecutionHandlerSelectors, _addIns, rtdServerTypes, comClassTypes);
286+
_extendedRegistrationConfiguration = new ExtendedRegistration.Registration.Configuration() { ParameterConversions = excelParameterConversions, ReturnConversions = excelReturnConversions, ExcelFunctionProcessors = excelFunctionProcessors, ExcelFunctionExecutionHandlerSelectors = excelFunctionExecutionHandlerSelectors };
287+
287288
NativeAOT.ExcelAddIns.ForEach(i => AssemblyLoader.GetExcelAddIns(null, i, _addIns));
288289

289290
// Register RTD Server Types (i.e. remember that these types are available as RTD servers, with relevant ProgId etc.)
@@ -329,8 +330,11 @@ internal void AutoOpen()
329330
AssemblyLoader.GetExcelMethods(NativeAOT.MethodsForRegistration, true, _methods, _excelFunctionsExtendedRegistration);
330331

331332
// Register my Methods
332-
var allMethods = _methods.Select(i => new Registration.ExcelFunctionRegistration(i)).Concat(_excelFunctionsExtendedRegistration);
333-
ExtendedRegistration.Registration.RegisterExtended(allMethods, _excelParameterConversions, _excelReturnConversions, _excelFunctionProcessors, _excelFunctionExecutionHandlerSelectors);
333+
List<MethodInfo> commands = _methods.Where(Registration.ExcelCommandRegistration.IsCommand).ToList();
334+
ExcelIntegration.RegisterMethods(commands);
335+
336+
var functions = _methods.Except(commands).Select(i => new Registration.ExcelFunctionRegistration(i)).Concat(_excelFunctionsExtendedRegistration);
337+
ExtendedRegistration.Registration.Register(functions, _extendedRegistrationConfiguration);
334338

335339
// Invoke AutoOpen in all assemblies
336340
foreach (AssemblyLoader.ExcelAddInInfo addIn in _addIns)
@@ -621,6 +625,14 @@ internal static string ExecutingDirectory
621625
}
622626
}
623627

628+
internal static ExtendedRegistration.Registration.Configuration ExtendedRegistrationConfiguration
629+
{
630+
get
631+
{
632+
return CurrentLibrary._extendedRegistrationConfiguration;
633+
}
634+
}
635+
624636
public string ResolvePath(string path)
625637
{
626638
return ResolvePath(path, dnaResolveRoot);

Source/ExcelDna.Integration/Excel.cs

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -758,23 +758,14 @@ internal static Guid GuidFromXllPath(string path)
758758
#endregion
759759

760760
#region ExcelLimits
761-
private static ExcelLimits _xlLimits;
762-
public static ExcelLimits ExcelLimits
761+
static readonly ExcelLimits _xlLimits = new ExcelLimits
763762
{
764-
get
765-
{
766-
if (_xlLimits == null)
767-
{
768-
_xlLimits = new ExcelLimits();
769-
770-
_xlLimits.MaxRows = 1048576;
771-
_xlLimits.MaxColumns = 16384;
772-
_xlLimits.MaxArguments = 256;
773-
_xlLimits.MaxStringLength = 32767;
774-
}
775-
return _xlLimits;
776-
}
777-
}
763+
MaxRows = 1048576,
764+
MaxColumns = 16384,
765+
MaxArguments = 256,
766+
MaxStringLength = 32767
767+
};
768+
public static ExcelLimits ExcelLimits => _xlLimits;
778769
#endregion
779770

780771
#region SupportsDynamicArrays

Source/ExcelDna.Integration/ExcelAttributes.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,22 @@ public ExcelFunctionAttribute(string description)
3838
{
3939
Description = description;
4040
}
41+
42+
public ExcelFunctionAttribute(ExcelFunctionAttribute src)
43+
{
44+
Category = src.Category;
45+
Name = src.Name;
46+
Description = src.Description;
47+
HelpTopic = src.HelpTopic;
48+
IsVolatile = src.IsVolatile;
49+
IsHidden = src.IsHidden;
50+
IsExceptionSafe = src.IsExceptionSafe;
51+
IsMacroType = src.IsMacroType;
52+
IsThreadSafe = src.IsThreadSafe;
53+
IsClusterSafe = src.IsClusterSafe;
54+
ExplicitRegistration = src.ExplicitRegistration;
55+
SuppressOverwriteError = src.SuppressOverwriteError;
56+
}
4157
}
4258

4359
/// <summary>

Source/ExcelDna.Integration/ExtendedRegistration/Registration.cs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,48 @@ namespace ExcelDna.Integration.ExtendedRegistration
1010
{
1111
internal class Registration
1212
{
13-
public static void RegisterExtended(IEnumerable<ExcelDna.Registration.ExcelFunctionRegistration> functions, IEnumerable<ExcelParameterConversion> parameterConversions, IEnumerable<ExcelReturnConversion> returnConversions, IEnumerable<ExcelFunctionProcessor> excelFunctionProcessors, IEnumerable<FunctionExecutionHandlerSelector> excelFunctionExecutionHandlerSelectors)
13+
public class Configuration
14+
{
15+
public IEnumerable<ExcelParameterConversion> ParameterConversions { get; set; }
16+
public IEnumerable<ExcelReturnConversion> ReturnConversions { get; set; }
17+
public IEnumerable<ExcelFunctionProcessor> ExcelFunctionProcessors { get; set; }
18+
public IEnumerable<FunctionExecutionHandlerSelector> ExcelFunctionExecutionHandlerSelectors { get; set; }
19+
}
20+
21+
public static void Register(IEnumerable<ExcelFunctionRegistration> functions, Configuration configuration)
22+
{
23+
Register(Process(functions, configuration));
24+
}
25+
26+
public static void Register(IEnumerable<ExcelFunctionRegistration> functions)
27+
{
28+
functions = functions.ToList();
29+
var lambdas = functions.Select(reg => reg.FunctionLambda).ToList();
30+
var attribs = functions.Select(reg => reg.FunctionAttribute).ToList<object>();
31+
var argAttribs = functions.Select(reg => reg.ParameterRegistrations.Select(pr => pr.ArgumentAttribute).ToList<object>()).ToList();
32+
ExcelIntegration.RegisterLambdaExpressions(lambdas, attribs, argAttribs);
33+
}
34+
35+
public static IEnumerable<ExcelFunctionRegistration> Process(IEnumerable<ExcelFunctionRegistration> functions, Configuration configuration)
1436
{
1537
// Set the Parameter Conversions before they are applied by the ProcessParameterConversions call below.
1638
// CONSIDER: We might change the registration to be an object...?
17-
var conversionConfig = GetParameterConversionConfig(parameterConversions, returnConversions);
39+
var conversionConfig = GetParameterConversionConfig(configuration.ParameterConversions, configuration.ReturnConversions);
1840

19-
var functionHandlerConfig = GetFunctionExecutionHandlerConfig(excelFunctionExecutionHandlerSelectors);
41+
var functionHandlerConfig = GetFunctionExecutionHandlerConfig(configuration.ExcelFunctionExecutionHandlerSelectors);
2042

21-
Register(functions
43+
return functions
2244
.UpdateRegistrationsForRangeParameters()
23-
.ProcessFunctionProcessors(excelFunctionProcessors, conversionConfig)
45+
.ProcessFunctionProcessors(configuration.ExcelFunctionProcessors, conversionConfig)
2446
.ProcessParameterConversions(conversionConfig)
2547
.ProcessAsyncRegistrations(nativeAsyncIfAvailable: false)
2648
.ProcessParamsRegistrations()
2749
.ProcessObjectHandles()
2850
.ProcessFunctionExecutionHandlers(functionHandlerConfig)
29-
);
30-
}
31-
32-
internal static void Register(IEnumerable<ExcelDna.Registration.ExcelFunctionRegistration> functions)
33-
{
34-
functions = functions.ToList();
35-
var lambdas = functions.Select(reg => reg.FunctionLambda).ToList();
36-
var attribs = functions.Select(reg => reg.FunctionAttribute).ToList<object>();
37-
var argAttribs = functions.Select(reg => reg.ParameterRegistrations.Select(pr => pr.ArgumentAttribute).ToList<object>()).ToList();
38-
ExcelIntegration.RegisterLambdaExpressions(lambdas, attribs, argAttribs);
51+
;
3952
}
4053

41-
static ParameterConversionConfiguration GetParameterConversionConfig(IEnumerable<ExcelParameterConversion> parameterConversions, IEnumerable<ExcelReturnConversion> returnConversions)
54+
private static ParameterConversionConfiguration GetParameterConversionConfig(IEnumerable<ExcelParameterConversion> parameterConversions, IEnumerable<ExcelReturnConversion> returnConversions)
4255
{
4356
// NOTE: The parameter conversion list is processed once per parameter.
4457
// Parameter conversions will apply from most inside, to most outside.
@@ -93,7 +106,7 @@ static ParameterConversionConfiguration GetParameterConversionConfig(IEnumerable
93106
return paramConversionConfig;
94107
}
95108

96-
static FunctionExecutionConfiguration GetFunctionExecutionHandlerConfig(IEnumerable<FunctionExecutionHandlerSelector> excelFunctionExecutionHandlerSelectors)
109+
private static FunctionExecutionConfiguration GetFunctionExecutionHandlerConfig(IEnumerable<FunctionExecutionHandlerSelector> excelFunctionExecutionHandlerSelectors)
97110
{
98111
FunctionExecutionConfiguration result = new FunctionExecutionConfiguration();
99112

Source/ExcelDna.Integration/Registration/AsyncRegistration.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public static class AsyncRegistration
4343
ParameterConversionRegistration.ApplyParameterConversions(reg, ObjectHandleRegistration.GetParameterConversionConfiguration());
4444
reg.FunctionLambda = WrapMethodObservable(reg.FunctionLambda, reg.Return.CustomAttributes);
4545
}
46-
else if (ReturnsTask(reg.FunctionLambda) || reg.FunctionAttribute is ExcelDna.Registration.ExcelAsyncFunctionAttribute)
46+
else if (ReturnsTask(reg.FunctionLambda) || reg.FunctionAttribute is ExcelAsyncFunctionAttribute)
4747
{
4848
ParameterConversionRegistration.ApplyParameterConversions(reg, ObjectHandleRegistration.GetParameterConversionConfiguration());
4949
if (HasCancellationToken(reg.FunctionLambda))
@@ -58,6 +58,9 @@ public static class AsyncRegistration
5858
reg.FunctionLambda = useNativeAsync ? WrapMethodNativeAsyncTask(reg.FunctionLambda)
5959
: WrapMethodRunTask(reg.FunctionLambda, reg.Return.CustomAttributes);
6060
}
61+
62+
if (reg.FunctionAttribute is ExcelAsyncFunctionAttribute)
63+
reg.FunctionAttribute = new ExcelFunctionAttribute(reg.FunctionAttribute);
6164
}
6265
// else do nothing to this registration
6366
}

Source/ExcelDna.Integration/Registration/ExcelCommandRegistration.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,10 @@ public ExcelCommandRegistration(MethodInfo methodInfo)
7777
CommandAttribute = new ExcelCommandAttribute { Name = methodInfo.Name };
7878
}
7979
}
80+
81+
internal static bool IsCommand(MethodInfo methodInfo)
82+
{
83+
return methodInfo.GetCustomAttribute<ExcelCommandAttribute>() != null;
84+
}
8085
}
8186
}

Source/ExcelDna.Integration/Registration/ExcelRegistration.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
using ExcelDna.Integration;
2-
using System;
32
using System.Collections.Generic;
43
using System.Linq;
54
using System.Reflection;
6-
using System.Text;
7-
using System.Threading.Tasks;
85

96
namespace ExcelDna.Registration
107
{
@@ -33,13 +30,22 @@ where mi.GetCustomAttribute<ExcelFunctionAttribute>() != null
3330
select new ExcelFunctionRegistration(mi);
3431
}
3532

33+
/// <summary>
34+
/// Prepares the given functions for registration with Excel-DNA.
35+
/// </summary>
36+
/// <param name="registrationEntries"></param>
37+
public static IEnumerable<ExcelFunctionRegistration> ProcessFunctions(this IEnumerable<ExcelFunctionRegistration> registrationEntries)
38+
{
39+
return Integration.ExtendedRegistration.Registration.Process(registrationEntries, DnaLibrary.ExtendedRegistrationConfiguration);
40+
}
41+
3642
/// <summary>
3743
/// Registers the given functions with Excel-DNA.
3844
/// </summary>
3945
/// <param name="registrationEntries"></param>
4046
public static void RegisterFunctions(this IEnumerable<ExcelFunctionRegistration> registrationEntries)
4147
{
42-
ExcelDna.Integration.ExtendedRegistration.Registration.Register(registrationEntries);
48+
Integration.ExtendedRegistration.Registration.Register(registrationEntries);
4349
}
4450

4551
/// <summary>
@@ -54,7 +60,7 @@ public static IEnumerable<ExcelCommandRegistration> GetExcelCommands()
5460
return from ass in ExcelIntegration.GetExportedAssemblies()
5561
from typ in ass.GetTypes()
5662
from mi in typ.GetMethods(BindingFlags.Public | BindingFlags.Static)
57-
where mi.GetCustomAttribute<ExcelCommandAttribute>() != null
63+
where ExcelCommandRegistration.IsCommand(mi)
5864
select new ExcelCommandRegistration(mi);
5965
}
6066

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using ExcelDna.Integration;
2+
3+
namespace ExcelDna.AddIn.RuntimeTests
4+
{
5+
public class AddIn : IExcelAddIn
6+
{
7+
public void AutoOpen()
8+
{
9+
DynamicFunctions.Register();
10+
}
11+
12+
public void AutoClose()
13+
{
14+
}
15+
}
16+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using ExcelDna.Registration;
2+
3+
namespace ExcelDna.AddIn.RuntimeTests
4+
{
5+
internal class DynamicFunctions
6+
{
7+
public static void Register()
8+
{
9+
{
10+
ExcelFunctionRegistration[] functions = {
11+
CreateRegistration(nameof(DynamicSayHello)),
12+
CreateRegistration(nameof(DynamicOptionalDouble)),
13+
ChangeName(CreateRegistration(nameof(ChangeMe)), "DynamicFunctionName"),
14+
};
15+
16+
ExcelRegistration.RegisterFunctions(ExcelRegistration.ProcessFunctions(functions));
17+
}
18+
{
19+
ExcelFunctionRegistration[] functions = {
20+
ChangeName(CreateRegistration(nameof(DynamicOptionalDouble)), "DynamicOptionalDoubleUnprocessed"),
21+
};
22+
23+
ExcelRegistration.RegisterFunctions(functions);
24+
}
25+
}
26+
27+
private static string DynamicSayHello(string name)
28+
{
29+
return $"Dynamic Hello {name}";
30+
}
31+
32+
private static string DynamicOptionalDouble(double d = 4.56)
33+
{
34+
return "Dynamic Optional VAL: " + d.ToString();
35+
}
36+
37+
private static string ChangeMe()
38+
{
39+
return $"Function {nameof(ChangeMe)}";
40+
}
41+
42+
private static ExcelFunctionRegistration ChangeName(ExcelFunctionRegistration reg, string name)
43+
{
44+
reg.FunctionAttribute.Name = name;
45+
return reg;
46+
}
47+
48+
private static ExcelFunctionRegistration CreateRegistration(string name)
49+
{
50+
return new ExcelFunctionRegistration(typeof(DynamicFunctions).GetMethod(name, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static));
51+
}
52+
}
53+
}

0 commit comments

Comments
 (0)