Example #1
0
        public LambdaExpression BuildStaticGetter(PropertyInfo propertyInfo, Type valueType = null)
        {
            var getMethod = ValidatePropertyAndGetAccessorMethod(propertyInfo, true, true);

            CacheKey cacheKey = null;

            if (EnableCaching)
            {
                cacheKey = new CacheKey(propertyInfo, null, valueType, null);
                if (getterCache.TryGetValue(cacheKey, out var cachedLambda))
                {
                    return(cachedLambda);
                }
            }

            var delegateType = GenericTypeExtensions.GetFuncGenericType(valueType ?? propertyInfo.PropertyType);

            var lambda = Expression.Lambda(
                delegateType,
                GetCastedValueExpression(Expression.Call(null, getMethod), valueType));

            if (EnableCaching)
            {
                getterCache.TryAdd(cacheKey, lambda);
            }

            return(lambda);
        }
Example #2
0
        public LambdaExpression BuildStaticSetter(PropertyInfo propertyInfo, Type valueType = null)
        {
            var setMethod = ValidatePropertyAndGetAccessorMethod(propertyInfo, true, false);

            valueType = valueType ?? propertyInfo.PropertyType;

            CacheKey cacheKey = null;

            if (EnableCaching)
            {
                cacheKey = new CacheKey(propertyInfo, null, valueType, null);
                if (setterCache.TryGetValue(cacheKey, out var cachedLambda))
                {
                    return(cachedLambda);
                }
            }

            var value        = Expression.Parameter(valueType, "value");
            var delegateType = GenericTypeExtensions.GetActionGenericType(valueType);

            var lambda = Expression.Lambda(
                delegateType,
                Expression.Call(null, setMethod, GetCastedValueExpression(value, propertyInfo.PropertyType)),
                value);

            if (EnableCaching)
            {
                getterCache.TryAdd(cacheKey, lambda);
            }

            return(lambda);
        }
Example #3
0
        public Delegate BuildStaticGetter(FieldInfo fieldInfo, Type valueType = null)
        {
            CacheKey cacheKey = null;

            if (EnableCaching)
            {
                cacheKey = new CacheKey(fieldInfo, null, valueType);
                if (getterCache.TryGetValue(cacheKey, out var cachedDelegate))
                {
                    return(cachedDelegate);
                }
            }

            Delegate _delegate;

            if (!fieldInfo.IsInitOnly)
            {
                _delegate = builder.BuildStaticGetter(fieldInfo, valueType).Compile();
            }
            else
#if NET45
            { _delegate = Emit.FieldAccessorMethodEmitter.GetFieldSetter(fieldInfo, GenericTypeExtensions.GetActionGenericType(valueType ?? fieldInfo.FieldType)); }
#else
            { throw new InvalidOperationException($"Field {fieldInfo.Name} is InitOnly and cannot be set."); }
#endif

            if (EnableCaching)
            {
                getterCache.TryAdd(cacheKey, _delegate);
            }

            return(_delegate);
        }
        public LambdaExpression BuildStaticGetter(FieldInfo fieldInfo, Type valueType = null)
        {
            ValidateField(fieldInfo, true);

            CacheKey cacheKey = null;

            if (EnableCaching)
            {
                cacheKey = new CacheKey(fieldInfo, null, valueType);
                if (getterCache.TryGetValue(cacheKey, out var cachedLambda))
                {
                    return(cachedLambda);
                }
            }

            var delegateType = GenericTypeExtensions.GetFuncGenericType(valueType ?? fieldInfo.FieldType);

            var lambda = Expression.Lambda(
                delegateType,
                GetCastedValueExpression(Expression.Field(null, fieldInfo), valueType));

            if (EnableCaching)
            {
                getterCache.TryAdd(cacheKey, lambda);
            }

            return(lambda);
        }
        public LambdaExpression BuildInstanceGetter(FieldInfo fieldInfo, Type instanceType = null, Type valueType = null)
        {
            ValidateField(fieldInfo, false);

            CacheKey cacheKey = null;

            if (EnableCaching)
            {
                cacheKey = new CacheKey(fieldInfo, instanceType, valueType);
                if (getterCache.TryGetValue(cacheKey, out var cachedLambda))
                {
                    return(cachedLambda);
                }
            }

            instanceType = instanceType ?? fieldInfo.DeclaringType;
            valueType    = valueType ?? fieldInfo.FieldType;

            var instance       = Expression.Parameter(instanceType, "instance");
            var castedInstance = GetCastedInstanceExpression(instance, fieldInfo);

            var delegateType = GenericTypeExtensions.GetFuncGenericType(instanceType, valueType);

            var lambda = Expression.Lambda(
                delegateType,
                GetCastedValueExpression(Expression.Field(castedInstance, fieldInfo), valueType),
                instance);

            if (EnableCaching)
            {
                getterCache.TryAdd(cacheKey, lambda);
            }

            return(lambda);
        }
        public void IsConcreteInstanceOfGenericTypeDefinition_TypesDoNotMatch_False()
        {
            var aType   = typeof(CommandError).GetTypeInfo();
            var generic = typeof(CommandResult <>);
            var result  = GenericTypeExtensions.IsConcreteInstanceOfGenericTypeDefinition(aType, generic);

            Assert.False(result);
        }
        public void GetConcreteInterfaceImplementationForGenericInterface_TypesDoNotMatch_Null()
        {
            var aType   = typeof(CommandError).GetTypeInfo();
            var generic = typeof(ICustomCommandHandler <,>);
            var result  = GenericTypeExtensions.GetConcreteInterfaceImplementationForGenericInterface(aType, generic);

            Assert.Null(result);
        }
        public void GetConcreteInterfaceImplementationForGenericInterface_TypesMatch_True()
        {
            var aType   = typeof(TestCommandHandler).GetTypeInfo();
            var generic = typeof(ICustomCommandHandler <,>);
            var result  = GenericTypeExtensions.GetConcreteInterfaceImplementationForGenericInterface(aType, generic);

            Assert.Equal(typeof(ICustomCommandHandler <TestCommand, CommandResult <CommandError> >), result);
        }
        public void GetConcreteInterfaceImplementationForGenericInterface_InterfaceNotGeneric_Throws()
        {
            var aType     = typeof(CommandError).GetTypeInfo();
            var generic   = typeof(IFormattable);
            var exception = Assert.Throws <ArgumentException>(() => GenericTypeExtensions.GetConcreteInterfaceImplementationForGenericInterface(aType, generic));

            AssertCorrectArgumentException(exception);
        }
        public LambdaExpression BuildInstanceSetter(FieldInfo fieldInfo, Type instanceType = null, Type valueType = null)
        {
            ValidateField(fieldInfo, false);

            CacheKey cacheKey = null;

            if (EnableCaching)
            {
                cacheKey = new CacheKey(fieldInfo, instanceType, valueType);
                if (setterCache.TryGetValue(cacheKey, out var cachedLambda))
                {
                    return(cachedLambda);
                }
            }

            instanceType = instanceType ?? fieldInfo.DeclaringType;
            valueType    = valueType ?? fieldInfo.FieldType;

            var instance = Expression.Parameter(instanceType, "instance");
            var value    = Expression.Parameter(valueType, "value");

            var expressionParameters = new[] { instance, value };

            var castedInstance = GetCastedInstanceExpression(instance, fieldInfo);

            var delegateType = GenericTypeExtensions.GetActionGenericType(instanceType, valueType);

            LambdaExpression lambda;

            if (!fieldInfo.IsInitOnly)
            {
                lambda = Expression.Lambda(
                    delegateType,
                    Expression.Assign(
                        Expression.Field(castedInstance, fieldInfo),
                        GetCastedValueExpression(value, fieldInfo.FieldType)),
                    expressionParameters);
            }
            else
            {
#if !NETSTANDARD2_0
                var m = Reflection.Emit.FieldAccessorMethodEmitter.GetFieldSetterMethod(fieldInfo, delegateType);
                lambda = Expression.Lambda(
                    delegateType,
                    Expression.Call(m, castedInstance, GetCastedValueExpression(value, fieldInfo.FieldType)),
                    expressionParameters);
#else
                throw new InvalidOperationException($"Field {fieldInfo.Name} is InitOnly and cannot be set.");
#endif
            }

            if (EnableCaching)
            {
                setterCache.TryAdd(cacheKey, lambda);
            }

            return(lambda);
        }
        public static Delegate GetFieldGetter(FieldInfo field, Type delegateType = null)
        {
            var method = GetFieldSetterMethod(field, delegateType);

            if (delegateType == null)
            {
                delegateType = GenericTypeExtensions.GetFuncGenericType((field.IsStatic ? new[] { field.DeclaringType } : new Type[] { }).Concat(new[] { field.FieldType }));
            }
            return(method.CreateDelegate(delegateType));
        }
Example #12
0
        public LambdaExpression BuildInstanceSetter(PropertyInfo propertyInfo, Type instanceType = null, Type valueType = null, IEnumerable <Type> indexerTypes = null)
        {
            var setMethod = ValidatePropertyAndGetAccessorMethod(propertyInfo, false, false);

            CacheKey cacheKey = null;

            if (EnableCaching)
            {
                cacheKey = new CacheKey(propertyInfo, instanceType, valueType, indexerTypes);
                if (setterCache.TryGetValue(cacheKey, out var cachedLambda))
                {
                    return(cachedLambda);
                }
            }

            instanceType = instanceType ?? propertyInfo.DeclaringType;
            valueType    = valueType ?? propertyInfo.PropertyType;

            var instance = Expression.Parameter(instanceType, "instance");
            var value    = Expression.Parameter(valueType, "value");

            var indexedParameters            = propertyInfo.GetIndexParameters();
            var indexedParametersExpressions = indexerTypes == null?
                                               indexedParameters.Select((x, i) => Expression.Parameter(x.ParameterType, "itemIndexer" + i)).ToList() :
                                                   indexedParameters.Zip(indexerTypes, (p, i) => new { p, i }).Select((x, i) => Expression.Parameter(x.i ?? x.p.ParameterType, "itemIndexer" + i)).ToList();

            var expressionParameters = new[] { instance }.Concat(indexedParametersExpressions).Concat(new[] { value });

            var castedInstance       = GetCastedInstanceExpression(instance, propertyInfo);
            var methodCallparameters = (indexerTypes == null ?
                                        indexedParametersExpressions :
                                        indexedParametersExpressions
                                        .Zip(indexedParameters, (p, i) => GetCastedValueExpression(p, i.ParameterType)))
                                       .Concat(new[] { GetCastedValueExpression(value, propertyInfo.PropertyType) });

            var delegateType = GenericTypeExtensions.GetActionGenericType(new Type[] { instanceType }.Concat(expressionParameters.Skip(1).Select(x => x.Type)));

            var lambda = Expression.Lambda(
                delegateType,
                Expression.Call(castedInstance, setMethod, methodCallparameters),
                expressionParameters);

            if (EnableCaching)
            {
                setterCache.TryAdd(cacheKey, lambda);
            }

            return(lambda);
        }
        private LambdaExpression BuildFromTypes(ConstructorInfo ctorInfo, Type instanceType, IEnumerable <Type> parameterTypes, Type delegateType)
        {
            CacheKey cacheKey = null;

            if (EnableCaching && delegateType == null)
            {
                cacheKey = new CacheKey(ctorInfo, instanceType, parameterTypes);
                if (cache.TryGetValue(cacheKey, out var lambda))
                {
                    return(lambda);
                }
            }

            var effectiveInstanceType = instanceType ?? ctorInfo.DeclaringType;

            var constructorParameters = ctorInfo.GetParameters()
                                        .ZipOutter(parameterTypes ?? Enumerable.Empty <Type>(),
                                                   (cp, p) => new
            {
                MethodType     = cp.ParameterType,
                Name           = cp.Name,
                InputParameter = Expression.Parameter(p ?? cp.ParameterType, cp.Name),
            })
                                        .Select(x => new
            {
                x.InputParameter,
                MethodCallParameter = x.MethodType == x.InputParameter.Type ? (Expression)x.InputParameter : ExpressionEx.ConvertIfNeeded(x.InputParameter, x.MethodType)
            })
                                        .ToList();

            var effectiveDelegateType = delegateType ?? GenericTypeExtensions.GetFuncGenericType(constructorParameters.Select(x => x.InputParameter.Type).Concat(new[] { effectiveInstanceType }));
            var invokerExpression     = (Expression)Expression.New(ctorInfo, constructorParameters.Select(x => x.MethodCallParameter));

            if (effectiveInstanceType != ctorInfo.DeclaringType)
            {
                invokerExpression = Expression.Convert(invokerExpression, effectiveInstanceType);
            }

            var l = Expression.Lambda(effectiveDelegateType, invokerExpression, constructorParameters.Select(x => x.InputParameter).ToArray());

            if (EnableCaching && delegateType == null)
            {
                cache.TryAdd(cacheKey, l);
            }

            return(l);
        }
        private LambdaExpression BuildInvokerExpressionFromTypes(MethodInfo methodInfo, Type instanceType, IEnumerable <Type> parameterTypes, Type returnType, Type delegateType)
        {
            if (methodInfo == null)
            {
                throw new ArgumentNullException(nameof(methodInfo));
            }

            CacheKey cacheKey = null;

            if (EnableCaching && delegateType != null)
            {
                cacheKey = new CacheKey(methodInfo, instanceType, returnType, parameterTypes);
                if (byTypesCache.TryGetValue(cacheKey, out var cachedLambda))
                {
                    return(cachedLambda);
                }
            }

            returnType   = returnType ?? methodInfo.ReturnType;
            instanceType = methodInfo.IsStatic ? null : instanceType ?? methodInfo.DeclaringType;

            var methodParameters =
                (methodInfo.IsStatic ?
                 Enumerable.Empty <MethodParameter>() :
                 new[] { new MethodParameter {
                             InputParameter = Expression.Parameter(instanceType, "instance"), MethodType = methodInfo.DeclaringType
                         } })
                .Concat(methodInfo.GetParameters().ZipOutter(parameterTypes ?? Enumerable.Empty <Type>(),
                                                             (mp, pt) => new MethodParameter
            {
                InputParameter = Expression.Parameter(pt ?? mp.ParameterType, mp.Name),
                MethodType     = mp.ParameterType
            }))
                .Select(x => new
            {
                x.InputParameter,
                MethodCallParameter = x.MethodType == x.InputParameter.Type ? (Expression)x.InputParameter : ExpressionEx.ConvertIfNeeded(x.InputParameter, x.MethodType)
            })
                .ToList();

            var isAction = methodInfo.ReturnType == typeof(void) && (returnType == null || returnType == typeof(void));

            var effectiveDelegateType = delegateType ?? (isAction ?
                                                         GenericTypeExtensions.GetActionGenericType(methodParameters.Select(x => x.MethodCallParameter.Type)) :
                                                         GenericTypeExtensions.GetFuncGenericType(methodParameters.Select(x => x.MethodCallParameter.Type).Concat(new[] { returnType }).ToArray()));

            var invokerExpression = Expression.Call(
                methodInfo.IsStatic ? null : methodParameters.Select(x => x.MethodCallParameter).First(),
                methodInfo,
                methodParameters.Select(x => x.MethodCallParameter).Skip(methodInfo.IsStatic ? 0 : 1));

            var body = methodInfo.ReturnType == typeof(void) ?
                       (!isAction ?
                        (Expression)Expression.Block(typeof(object), invokerExpression, Expression.Constant(null)) :
                        invokerExpression) :
                       Expression.Convert(invokerExpression, returnType);

            var lambda = Expression.Lambda(effectiveDelegateType, body, methodParameters.Select(x => x.InputParameter));

            if (EnableCaching && delegateType != null)
            {
                byTypesCache.TryAdd(cacheKey, lambda);
            }

            return(lambda);
        }
        public Expression <Action <object, object> > BuildGenericSetter(FieldInfo fieldInfo)
        {
            ValidateField(fieldInfo, null);

            if (EnableCaching &&
                genericSetterCache.TryGetValue(fieldInfo, out var cachedLambda))
            {
                return((Expression <Action <object, object> >)cachedLambda);
            }

            var instanceParameter = Expression.Parameter(typeof(object), "instance");
            var value             = Expression.Parameter(typeof(object), "value");
            var castedInstance    = ExpressionEx.ConvertIfNeeded(instanceParameter, fieldInfo.DeclaringType);

            Expression <Action <object, object> > lambda;

            if (!fieldInfo.IsInitOnly)
            {
                lambda = Expression.Lambda <Action <object, object> >(
                    Expression.Assign(
                        Expression.Field(fieldInfo.IsStatic ? null : castedInstance, fieldInfo),
                        GetCastedValueExpression(value, fieldInfo.FieldType)),
                    instanceParameter, value);
            }
            else
            {
#if !NETSTANDARD2_0
                var m = Reflection.Emit.FieldAccessorMethodEmitter.GetFieldSetterMethod(fieldInfo, GenericTypeExtensions.GetActionGenericType(fieldInfo.DeclaringType, fieldInfo.FieldType));
                lambda = Expression.Lambda <Action <object, object> >(
                    Expression.Call(m, castedInstance, GetCastedValueExpression(value, fieldInfo.FieldType)),
                    instanceParameter, value);
#else
                throw new InvalidOperationException($"Field {fieldInfo.Name} is InitOnly and cannot be set.");
#endif
            }

            if (EnableCaching)
            {
                genericGetterCache.TryAdd(fieldInfo, lambda);
            }

            return(lambda);
        }