Exemplo n.º 1
0
        /// <summary>
        /// Creates the HTML object for each property that is part of the parent.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="attribute">The attribute.</param>
        /// <param name="nativeAttributes">The native attributes.</param>
        /// <returns>The expressions needed to create the list</returns>
        private IEnumerable <Expression> CreateWinControlObject(ControlBuilderContext context, ControlLocatorAttribute attribute, IEnumerable nativeAttributes)
        {
            var buildElement = context.CurrentControl ?? context.Window;
            var objectType   = this.GetPropertyProxyType(buildElement.Type);

            var propConstructor = this.GetConstructor(objectType, context);

            if (propConstructor == null)
            {
                throw this.CreateConstructorException(buildElement.Name, objectType);
            }

            var itemVariable = buildElement.Expression;

            return(new[]
            {
                (Expression)Expression.Assign(itemVariable, Expression.New(propConstructor.Item1, propConstructor.Item2)),
                Expression.Call(
                    Expression.Constant(this),
                    this.assignMethodInfo,
                    Expression.Convert(itemVariable, typeof(TControl)),
                    Expression.Constant(attribute, typeof(ControlLocatorAttribute)),
                    Expression.Constant(nativeAttributes, typeof(object[])))
            });
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates the new item expression that creates the object and initial mapping.
        /// </summary>
        /// <param name="controlType">Type of the control.</param>
        /// <returns>The initial creation lambda expression.</returns>
        /// <exception cref="System.InvalidOperationException">Thrown if the constructor is invalid.</exception>
        private Expression <Func <TParent, TApplication, Action <TOutput>, TOutput> > CreateNewItemExpression(Type controlType)
        {
            var applicationParameter = Expression.Parameter(typeof(TApplication), "application");
            var applicationArgument  = new ExpressionData(applicationParameter, typeof(TApplication), "application");

            var parentParameter = Expression.Parameter(typeof(TParent), "parent");
            var parentArgument  = new ExpressionData(parentParameter, typeof(TParent), "rootContext");

            var controlVariable = Expression.Variable(controlType);
            var controlData     = new ExpressionData(controlVariable, controlType, controlType.Name);

            var context = new ControlBuilderContext(applicationArgument, parentArgument, controlData);

            var constructor = this.GetConstructor(controlType, context);

            if (constructor == null)
            {
                throw this.CreateConstructorException(null, controlType);
            }

            var actionParameter = Expression.Parameter(typeof(Action <TOutput>), "action");

            // Spin though properties and make an initializer for anything we can set that has an attribute
            var pageMethodInfo = new Action <TOutput, Action <TOutput> >(this.AssignWindowAttributes).GetMethodInfo();
            var expressions    = new List <Expression>
            {
                Expression.Assign(controlVariable, Expression.New(constructor.Item1, constructor.Item2)),
                Expression.Call(
                    Expression.Constant(this),
                    pageMethodInfo,
                    Expression.Convert(controlVariable, typeof(TOutput)),
                    actionParameter)
            };

            this.MapObjectProperties(expressions, controlType, context);
            expressions.Add(controlVariable);

            var methodCall = Expression.Block(new[] { controlVariable }, expressions);

            return(Expression.Lambda <Func <TParent, TApplication, Action <TOutput>, TOutput> >(methodCall, parentParameter, applicationParameter, actionParameter));
        }
Exemplo n.º 3
0
        /// <summary>
        /// Maps the object properties for the given object.
        /// </summary>
        /// <param name="expressions">The parent expression list.</param>
        /// <param name="objectType">Type of the object.</param>
        /// <param name="context">The window builder context.</param>
        private void MapObjectProperties(ICollection <Expression> expressions, Type objectType, ControlBuilderContext context)
        {
            // ReSharper disable LoopCanBeConvertedToQuery
            foreach (var propertyInfo in objectType.GetProperties().Where(p =>
                                                                          p.SetMethod != null && p.CanWrite && p.PropertyType.IsSupportedPropertyType(typeof(TControl))))
            {
                var propertyType     = propertyInfo.PropertyType;
                var attribute        = propertyInfo.GetCustomAttributes(typeof(ControlLocatorAttribute), false).FirstOrDefault() as ControlLocatorAttribute;
                var customAttributes = this.GetCustomAttributes(propertyInfo);
                if (attribute == null && customAttributes.Length == 0)
                {
                    continue;
                }

                // Final Properties
                var itemVariable = Expression.Variable(propertyType);
                context.CurrentControl = new ExpressionData(itemVariable, propertyType, propertyInfo.Name);

                var variableList = new List <ParameterExpression> {
                    itemVariable
                };
                var propertyExpressions = new List <Expression>();

                // New up property and then check it for inner properties.
                var childContext = context.CreateChildContext(context.CurrentControl);

                propertyExpressions.AddRange(this.CreateWinControlObject(childContext, attribute, customAttributes));
                this.MapObjectProperties(propertyExpressions, propertyType, childContext);

                propertyExpressions.Add(Expression.Assign(Expression.Property(context.Window.Expression, propertyInfo), itemVariable));
                expressions.Add(Expression.Block(variableList, propertyExpressions));
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Gets the constructor.
        /// </summary>
        /// <param name="itemType">Type of the item.</param>
        /// <param name="context">The window builder context.</param>
        /// <returns>The constructor information that matches.</returns>
        private Tuple <ConstructorInfo, IEnumerable <Expression> > GetConstructor(Type itemType, ControlBuilderContext context)
        {
            ConstructorInfo emptyConstructor = null;

            foreach (var constructorInfo in itemType
                     .GetConstructors(BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                     .OrderByDescending(c => c.GetParameters().Length))
            {
                var parameters = constructorInfo.GetParameters();
                if (parameters.Length == 0)
                {
                    emptyConstructor = constructorInfo;
                    continue;
                }

                var slots = new Expression[parameters.Length];
                slots.Initialize();

                for (var i = 0; i < parameters.Length; i++)
                {
                    var parameter     = parameters[i];
                    var parameterType = parameter.ParameterType;

                    if (context.Window.Type.IsAssignableFrom(parameterType))
                    {
                        slots[i] = Expression.Convert(context.Window.Expression, context.Window.Type);
                    }
                    else
                    {
                        slots[i] = this.FillConstructorParameter(parameterType, context.ParentControl, context.RootLocator);
                    }
                }

                if (slots.All(s => s != null))
                {
                    return(new Tuple <ConstructorInfo, IEnumerable <Expression> >(constructorInfo, slots));
                }
            }

            return(this.AllowEmptyConstructor && emptyConstructor != null
                ? new Tuple <ConstructorInfo, IEnumerable <Expression> >(emptyConstructor, new List <Expression>(0))
                : null);
        }