Пример #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DataBindingSetterBuilder"/> class.
        /// </summary>
        /// <param name="expressionType">The type of the bound expression.</param>
        /// <param name="dataSourceType">The type of the data source to which the value is being bound.</param>
        /// <param name="expression">The binding expression with which to bind the dependency property.</param>
        public DataBindingSetterBuilder(Type expressionType, Type dataSourceType, String expression)
            : base(dataSourceType)
        {
            this.boundType    = expressionType;
            this.delegateType = typeof(DataBindingSetter <>).MakeGenericType(expressionType);

            if (UltravioletPlatformInfo.IsRuntimeCodeGenerationSupported())
            {
                CreateReturnTarget();

                var path          = BindingExpressions.GetBindingMemberPathPart(expression);
                var pathParts     = path.Contains(".") ? path.Split('.') : null;
                var pathFinalPart = (pathParts == null) ? path : pathParts[pathParts.Length - 1];

                var current = AddDataSourceReference();
                var value   = AddValueParameter();

                if (current.Type.IsValueType)
                {
                    return;
                }

                if (pathParts != null)
                {
                    for (int i = 0; i < pathParts.Length - 1; i++)
                    {
                        current = AddSafeReference(expression, current, pathParts[i]);
                    }
                }

                if (!AddValueAssignment(current, value, pathFinalPart))
                {
                    return;
                }

                AddReturn();
                AddReturnLabel();

                var lambdaBody = Expression.Block(variables, expressions);
                var lambda     = Expression.Lambda(delegateType, lambdaBody, parameters);

                lambdaExpression = lambda;
            }
            else
            {
                var expParamDataSource = Expression.Parameter(typeof(Object), "dataSource");
                var expParamValue      = Expression.Parameter(boundType, "value");

                var implMethod = typeof(DataBindingSetterBuilder).GetMethod(nameof(ReflectionBasedImplementation),
                                                                            BindingFlags.NonPublic | BindingFlags.Static);

                var path          = BindingExpressions.GetBindingMemberPathPart(expression);
                var pathParts     = path.Contains(".") ? path.Split('.') : null;
                var pathFinalPart = (pathParts == null) ? path : pathParts[pathParts.Length - 1];

                var expDataSource     = (Expression)Expression.Convert(expParamDataSource, dataSourceType);
                var expDataSourceType = dataSourceType;

                var current = dataSourceType;
                if (pathParts != null)
                {
                    for (int i = 0; i < pathParts.Length - 1; i++)
                    {
                        expDataSourceType = BindingExpressions.GetMemberType(BindingExpressions.FindPropertyOrField(expDataSourceType, pathParts[i]));
                        expDataSource     = Expression.PropertyOrField(expDataSource, pathParts[i]);
                    }
                }

                var member = BindingExpressions.FindPropertyOrField(expDataSourceType, pathFinalPart);
                if (!BindingExpressions.CanWriteMember(member))
                {
                    return;
                }

                var expImplMethodCall = Expression.Call(implMethod,
                                                        Expression.Constant(member),
                                                        Expression.Convert(expDataSource, typeof(Object)),
                                                        Expression.Convert(expParamValue, typeof(Object)));

                lambdaExpression = Expression.Lambda(delegateType, expImplMethodCall, expParamDataSource, expParamValue);
            }
        }