public AssignPropertyBuilder(DependencyEngine engine, Expression <Func <T> > targetMemberExpression, string nodeId) { var memberExpression = targetMemberExpression.Body as MemberExpression; if (memberExpression == null) { throw new ArgumentException("Expression must be a member (field/property) accessor, for example foo.Bar", "targetMemberExpression"); } var propertyInfo = memberExpression.Member as PropertyInfo; var fieldInfo = memberExpression.Member as FieldInfo; if (propertyInfo == null && fieldInfo == null) { throw new ArgumentException("Only fields and properties are supported", "targetMemberExpression"); } if (propertyInfo != null && !propertyInfo.CanWrite) { throw new ArgumentException("Property must be writable", "targetMemberExpression"); } if (fieldInfo != null && fieldInfo.IsInitOnly) { throw new ArgumentException("Field cannot be read-only", "targetMemberExpression"); } this.engine = engine; targetMemberDefinition = CreateMemberDefinition(targetMemberExpression, nodeId, true, true); }
// TODO this needs to go somewhere else, some factory public static MemberDefinition <T> CreateMemberDefinition <T>(Expression <Func <T> > expression, string nodeId, bool calculateChildren, bool isWritable, string pathOverride = null) { var parameterExpression = Expression.Parameter(typeof(T)); var targetAssignmentLambda = isWritable ? Expression.Lambda <Action <T> >(Expression.Assign(expression.Body, parameterExpression), parameterExpression) : null; var memberDefinition = new MemberDefinition <T>(expression, targetAssignmentLambda, nodeId, isWritable, pathOverride); if (calculateChildren) { var sourceDefinitions = ExpressionParser.GetChildSources(expression); // Property expressions always return themselves as a child, so skip memberDefinition.SourcePaths.AddRange(sourceDefinitions.Single().SourcePaths); } return(memberDefinition); }
static bool IsRoot <T>(MemberDefinition <T> memberDefinition) { return(!memberDefinition.SourcePaths.Any(s => s.FullPath != "this")); }