/// <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); } }