public static string DefaultArgName(Type argType) { if (argType.IsArray) { return(DefaultArgName(argType.GetElementType()) + "Array"); } if (EnumerablePolicy.IsEnumerable(argType)) { var argPrefix = DefaultArgName(EnumerablePolicy.DetermineElementType(argType)); var suffix = argType.GetGenericTypeDefinition().Name.Split('`').First(); return(argPrefix + suffix); } var parts = argType.Name.SplitPascalCase().Split(' '); if (argType.GetTypeInfo().IsInterface&& parts.First() == "I") { parts = parts.Skip(1).ToArray(); } var raw = (parts.First().ToLower() + parts.Skip(1).Join("")).Split('`').First(); return(raw); }
public static (Delegate func, Type funcType) LambdaTypeFor(Type serviceType, Type concreteType, ConstructorInfo ctor) { var length = ctor.GetParameters().Length; var openType = _openTypes[length]; var parameters = ctor.GetParameters(); var arguments = new ParameterExpression[parameters.Length]; var ctorParams = new Expression[parameters.Length]; var parameterTypes = new List <Type>(); for (var i = 0; i < parameters.Length; i++) { var parameter = parameters[i]; if (parameter.ParameterType.MustBeBuiltWithFunc()) { arguments[i] = Expression.Parameter(typeof(object)); if (EnumerablePolicy.IsEnumerable(parameter.ParameterType)) { var elementType = EnumerablePolicy.DetermineElementType(parameter.ParameterType); var coerceMethod = (parameter.ParameterType.IsArray ? _coerceToArray : _coerceToList) .MakeGenericMethod(elementType); ctorParams[i] = Expression.Call(coerceMethod, arguments[i]); } else { ctorParams[i] = Expression.Convert(arguments[i], parameter.ParameterType); } parameterTypes.Add(typeof(object)); } else { ctorParams[i] = arguments[i] = Expression.Parameter(parameter.ParameterType); parameterTypes.Add(parameter.ParameterType); } } var parameterType = serviceType.MustBeBuiltWithFunc() ? typeof(object) : serviceType; parameterTypes.Add(parameterType); var funcType = openType.MakeGenericType(parameterTypes.ToArray()); if (funcType.MustBeBuiltWithFunc()) { throw new InvalidOperationException( $"The Func of signature {funcType.NameInCode()} is not publicly accessible for type {serviceType.FullNameInCode()}"); } var callCtor = Expression.New(ctor, ctorParams); var lambda = Expression.Lambda(funcType, callCtor, arguments); const int FastExpressionCompilerParameterLimit = 8; if (parameterTypes.Count > FastExpressionCompilerParameterLimit) { var bigAssFunc = lambda.Compile(); return(bigAssFunc, funcType); } var func = lambda.CompileFast(); return(func, funcType); }