/// <summary>
        /// Adds properties as observables from a given type and optionally exluding properties from a given type that is found in the inheritance chain
        /// </summary>
        /// <param name="container"><see cref="Container"/> to add properties to</param>
        /// <param name="type"><see cref="Type"/> to get properties from</param>
        /// <param name="excludePropertiesFrom">Optional <see cref="Type"/> to use as basis for excluding properties</param>
        /// <param name="propertyVisitor">Optional visitor that gets called for every property - return false will ignore the property</param>
        /// <param name="assignmentVisitor">Optional <see cref="Action{Assignment}">visitor</see> that gets called for every assignment for any property</param>
        /// <param name="observableVisitor">Optional <see cref="Action{Observable}">visitor</see> that gets called for every observable property</param>
        /// <returns><see cref="Container"/> to keep building on</returns>
        public static Container WithObservablePropertiesFrom(this Container container, Type type, Type excludePropertiesFrom = null, Func<PropertyInfo, bool> propertyVisitor = null, Action<Assignment> assignmentVisitor = null, ObservableVisitor observableVisitor = null)
        {
            var properties = type.GetProperties();
            if (excludePropertiesFrom != null)
                properties = properties.Where(p => !excludePropertiesFrom.GetProperties().Select(pi => pi.Name).Contains(p.Name)).ToArray();

            if (propertyVisitor != null)
                properties = properties.Where(propertyVisitor).ToArray();

            AddObservablePropertiesFromType(container, properties, assignmentVisitor, observableVisitor);

            return container;
        }
Exemple #2
0
        /// <summary>
        /// Assign an observable
        /// </summary>
        /// <param name="assignment"><see cref="Assignment"/> to assign to</param>
        /// <param name="visitor">Optional <see cref="Action{Observable}"/> that gets called to build the observable</param>
        /// <returns>The <see cref="Assignment"/> to build on</returns>
        public static Assignment WithObservable(this Assignment assignment, ObservableVisitor visitor = null)
        {
            var observable = new Observable();

            assignment.Value = observable;

            if (visitor != null)
            {
                visitor(assignment.Name, observable);
            }

            return(assignment);
        }
        /// <summary>
        /// Assign an observable
        /// </summary>
        /// <param name="assignment"><see cref="Assignment"/> to assign to</param>
        /// <param name="visitor">Optional <see cref="Action{Observable}"/> that gets called to build the observable</param>
        /// <returns>The <see cref="Assignment"/> to build on</returns>
        public static Assignment WithObservable(this Assignment assignment, ObservableVisitor visitor = null)
        {
            var observable = new Observable();
            assignment.Value = observable;

            if (visitor != null) visitor(assignment.Name, observable);

            return assignment;
        }
        /// <summary>
        /// Adds properties as observables from a given type and optionally exluding properties from a given type that is found in the inheritance chain
        /// </summary>
        /// <param name="container"><see cref="Container"/> to add properties to</param>
        /// <param name="type"><see cref="Type"/> to get properties from</param>
        /// <param name="excludePropertiesFrom">Optional <see cref="Type"/> to use as basis for excluding properties</param>
        /// <param name="propertyVisitor">Optional visitor that gets called for every property - return false will ignore the property</param>
        /// <param name="assignmentVisitor">Optional <see cref="Action{Assignment}">visitor</see> that gets called for every assignment for any property</param>
        /// <param name="observableVisitor">Optional <see cref="Action{Observable}">visitor</see> that gets called for every observable property</param>
        /// <returns><see cref="Container"/> to keep building on</returns>
        public static Container WithObservablePropertiesFrom(this Container container, Type type, Type excludePropertiesFrom = null, Func <PropertyInfo, bool> propertyVisitor = null, Action <Assignment> assignmentVisitor = null, ObservableVisitor observableVisitor = null)
        {
            var properties = type.GetProperties();

            if (excludePropertiesFrom != null)
            {
                properties = properties.Where(p => !excludePropertiesFrom.GetProperties().Select(pi => pi.Name).Contains(p.Name)).ToArray();
            }

            if (propertyVisitor != null)
            {
                properties = properties.Where(propertyVisitor).ToArray();
            }

            AddObservablePropertiesFromType(container, properties, assignmentVisitor, observableVisitor);

            return(container);
        }
        static void AddObservablePropertiesFromType(Container parent, IEnumerable <PropertyInfo> properties, Action <Assignment> assignmentVisitor, ObservableVisitor observableVisitor)
        {
            foreach (var property in properties)
            {
                var propertyName = property.Name.ToCamelCase();

                Assignment assignment;
                if (parent is FunctionBody)
                {
                    assignment = new PropertyAssignment(propertyName);
                }
                else
                {
                    assignment = new KeyAssignment(propertyName);
                }

                if (property.IsDictionary())
                {
                    assignment.WithObjectLiteral();
                }
                else if (property.IsEnumerable())
                {
                    assignment.WithObservableArray();
                }
                else if (property.IsObservable())
                {
                    assignment.WithObservable(observableVisitor);
                }
                else
                {
                    var objectLiteral = new ObjectLiteral();
                    assignment.Value = objectLiteral;
                    AddObservablePropertiesFromType(objectLiteral, property.PropertyType.GetProperties(), assignmentVisitor, observableVisitor);
                }

                if (assignmentVisitor != null)
                {
                    assignmentVisitor(assignment);
                }

                parent.AddChild(assignment);
            }
        }
        static void AddObservablePropertiesFromType(Container parent, IEnumerable<PropertyInfo> properties, Action<Assignment> assignmentVisitor, ObservableVisitor observableVisitor)
        {
            foreach (var property in properties)
            {
                var propertyName = property.Name.ToCamelCase();

                Assignment assignment;
                if (parent is FunctionBody)
                    assignment = new PropertyAssignment(propertyName);
                else
                    assignment = new KeyAssignment(propertyName);

                if (property.IsDictionary())
                    assignment.WithObjectLiteral();
                else if (property.IsEnumerable())
                    assignment.WithObservableArray();
                else if (property.IsObservable())
                    assignment.WithObservable(observableVisitor);
                else
                {
                    var objectLiteral = new ObjectLiteral();
                    assignment.Value = objectLiteral;
                    AddObservablePropertiesFromType(objectLiteral, property.PropertyType.GetProperties(), assignmentVisitor, observableVisitor);
                }

                if (assignmentVisitor != null) assignmentVisitor(assignment);

                parent.AddChild(assignment);

            }
        }