示例#1
0
        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);
        }
示例#2
0
        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);
        }