|
| 1 | +using System; |
| 2 | +using System.Collections.Generic; |
| 3 | +using System.Linq; |
| 4 | +using System.Linq.Expressions; |
| 5 | +using System.Reflection; |
| 6 | +using ExcelDna.Integration; |
| 7 | + |
| 8 | +namespace ExcelDna.CustomRegistration |
| 9 | +{ |
| 10 | + public class RegistrationEntry |
| 11 | + { |
| 12 | + public LambdaExpression FunctionLambda { get; set; } // Function which will be registered, and invoked by Excel |
| 13 | + public ExcelFunctionAttribute FunctionAttribute { get; set; } // ExcelFunctionAttribute which is registered with Excel. Must not be null |
| 14 | + public List<ExcelArgumentAttribute> ArgumentAttributes { get; set; } // A list of ExcelArgumentAttributes with length equal to the number of parameters in Delegate |
| 15 | + public MethodInfo MethodInfo { get; private set; } // The method this entry was originally constructed with (may be useful for transformations). |
| 16 | + |
| 17 | + // NOTE: 16 parameter max for Expression.GetDelegateType |
| 18 | + public RegistrationEntry(MethodInfo methodInfo) |
| 19 | + { |
| 20 | + MethodInfo = methodInfo; |
| 21 | + |
| 22 | + var paramExprs = methodInfo.GetParameters() |
| 23 | + .Select(pi => Expression.Parameter(pi.ParameterType, pi.Name)) |
| 24 | + .ToArray(); |
| 25 | + FunctionLambda = Expression.Lambda(Expression.Call(methodInfo, paramExprs), methodInfo.Name, paramExprs); |
| 26 | + |
| 27 | + // Need to make sure we have explicit |
| 28 | + FunctionAttribute = methodInfo.GetCustomAttribute<ExcelFunctionAttribute>(); |
| 29 | + if (FunctionAttribute == null) |
| 30 | + FunctionAttribute = new ExcelFunctionAttribute { Name = methodInfo.Name }; |
| 31 | + else if (string.IsNullOrEmpty(FunctionAttribute.Name)) |
| 32 | + FunctionAttribute.Name = methodInfo.Name; |
| 33 | + |
| 34 | + ArgumentAttributes = new List<ExcelArgumentAttribute>(); |
| 35 | + foreach (var pi in methodInfo.GetParameters()) |
| 36 | + { |
| 37 | + var argAtt = pi.GetCustomAttribute<ExcelArgumentAttribute>(); |
| 38 | + if (argAtt == null) |
| 39 | + argAtt = new ExcelArgumentAttribute { Name = pi.Name }; |
| 40 | + else if (string.IsNullOrEmpty(argAtt.Name)) |
| 41 | + argAtt.Name = pi.Name; |
| 42 | + |
| 43 | + ArgumentAttributes.Add(argAtt); |
| 44 | + } |
| 45 | + |
| 46 | + // Special check for final Params argument - transform to an ExcelParamsArgumentAttribute |
| 47 | + // NOTE: This won't work with a custom derived attribute... |
| 48 | + var lastParam = methodInfo.GetParameters().LastOrDefault(); |
| 49 | + if (lastParam != null && lastParam.GetCustomAttribute<ParamArrayAttribute>() != null) |
| 50 | + { |
| 51 | + var excelParamsAtt = new Registration.ExcelParamsArgumentAttribute(ArgumentAttributes.Last()); |
| 52 | + ArgumentAttributes[ArgumentAttributes.Count - 1] = excelParamsAtt; |
| 53 | + } |
| 54 | + } |
| 55 | + } |
| 56 | +} |
0 commit comments