internal static ObjectCreateInfo MakeSelectInfo(Type type)
        {
            lock (_selectedTypeInfo)
            {
                ObjectCreateInfo info;
                if (_selectedTypeInfo.TryGetValue(type, out info)) return info;

                info = new ObjectCreateInfo(type.GetPropertiesEx().Select(e=> new ObjectCreateMemberInfo(e.Name, null)), null);
                _selectedTypeInfo[type] = info;
                return info;
            }
        }
        private void AddTypeMembers(Type type, XmlSerializerTypeInfo serializerTypeInfo)
        {
            var typesToCheck = new List<Type>();

            var isModelBase = type.IsModelBase();
            if (isModelBase)
            {
                // No need to check members, they will be serialized by ModelBase
                //var catelTypeInfo = PropertyDataManager.Default.GetCatelTypeInfo(type);
                //var modelBaseProperties = catelTypeInfo.GetCatelProperties();
                //foreach (var modelBaseProperty in modelBaseProperties)
                //{
                //    typesToCheck.Add(modelBaseProperty.Value.Type);
                //}
            }
            else
            {
                var allowNonPublicReflection = AllowNonPublicReflection(type);

                // Fields
                var fields = type.GetFieldsEx(BindingFlagsHelper.GetFinalBindingFlags(false, false, allowNonPublicReflection));
                foreach (var field in fields)
                {
                    typesToCheck.Add(field.FieldType);
                }

                // Properties
                var properties = type.GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(false, false, allowNonPublicReflection));
                foreach (var property in properties)
                {
                    typesToCheck.Add(property.PropertyType);
                }
            }

            foreach (var typeToCheck in typesToCheck)
            {
                if (serializerTypeInfo.IsTypeAlreadyHandled(typeToCheck))
                {
                    continue;
                }

                if (!IsTypeSerializable(typeToCheck, serializerTypeInfo))
                {
                    serializerTypeInfo.AddTypeAsHandled(typeToCheck);
                    continue;
                }

                var propertyTypeFullName = typeToCheck.GetSafeFullName();
                if (propertyTypeFullName == null)
                {
                    serializerTypeInfo.AddTypeAsHandled(typeToCheck);
                    continue;
                }

                GetKnownTypes(typeToCheck, serializerTypeInfo);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Initializes the view model meta data.
        /// <para />
        /// This method only initializes the meta data once per view model type. If a type is already initialized,
        /// this method will immediately return.
        /// </summary>
        /// <param name="viewModelType">Type of the view model.</param>
        /// <returns>ViewModelMetadata.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="viewModelType" /> is <c>null</c>.</exception>
        private static ViewModelMetadata InitializeViewModelMetaData(Type viewModelType)
        {
            if (_metaData.ContainsKey(viewModelType))
            {
                return _metaData[viewModelType];
            }

            var properties = new List<PropertyInfo>();
            var bindingFlags = BindingFlagsHelper.GetFinalBindingFlags(true, false, true);
            properties.AddRange(viewModelType.GetPropertiesEx(bindingFlags));

            var modelObjectsInfo = new Dictionary<string, ModelInfo>();
            var viewModelToModelMap = new Dictionary<string, ViewModelToModelMapping>();
            var validationSummaries = new Dictionary<string, ValidationToViewModelAttribute>();

            var modelNames = (from propertyInfo in properties
                              where propertyInfo.IsDecoratedWithAttribute<ModelAttribute>()
                              select propertyInfo.Name).ToList();

            foreach (var propertyInfo in properties)
            {
                #region Model attributes
                var modelAttribute = propertyInfo.GetCustomAttributeEx(typeof(ModelAttribute), true) as ModelAttribute;
                if (modelAttribute != null)
                {
                    modelObjectsInfo.Add(propertyInfo.Name, new ModelInfo(propertyInfo.Name, modelAttribute));
                }
                #endregion

                #region ViewModelToModel attributes
                var viewModelToModelAttribute = propertyInfo.GetCustomAttributeEx(typeof(ViewModelToModelAttribute), true) as ViewModelToModelAttribute;
                if (viewModelToModelAttribute != null)
                {
                    if (string.IsNullOrEmpty(viewModelToModelAttribute.Property))
                    {
                        // Assume the property name in the model is the same as in the view model
                        viewModelToModelAttribute.Property = propertyInfo.Name;
                    }

                    if (string.IsNullOrWhiteSpace(viewModelToModelAttribute.Model))
                    {
                        Log.Debug("ViewToViewModel is missing the Model name, searching for the right model automatically");

                        if (modelNames.Count != 1)
                        {
                            throw Log.ErrorAndCreateException<InvalidOperationException>("It is only possible to automatically select the right model if there is 1 model. There are '{0}' models, so please specify the model name explicitly.", modelNames.Count);
                        }

                        viewModelToModelAttribute.Model = modelNames[0];
                    }

                    if (!viewModelToModelMap.ContainsKey(propertyInfo.Name))
                    {
                        viewModelToModelMap.Add(propertyInfo.Name, new ViewModelToModelMapping(propertyInfo.Name, viewModelToModelAttribute));
                    }
                }
                #endregion

                #region ValidationToViewModel attributes
                var validationToViewModelAttribute = propertyInfo.GetCustomAttributeEx(typeof(ValidationToViewModelAttribute), true) as ValidationToViewModelAttribute;
                if (validationToViewModelAttribute != null)
                {
                    if (propertyInfo.PropertyType != typeof(IValidationSummary))
                    {
                        throw Log.ErrorAndCreateException<InvalidOperationException>("A property decorated with the ValidationToViewModel attribute must be of type IValidationSummary, but '{0}' is not", propertyInfo.Name);
                    }

                    validationSummaries.Add(propertyInfo.Name, validationToViewModelAttribute);

                    Log.Debug("Registered property '{0}' as validation summary", propertyInfo.Name);
                }
                #endregion
            }

            _metaData.Add(viewModelType, new ViewModelMetadata(viewModelType, modelObjectsInfo, viewModelToModelMap, validationSummaries));

            return _metaData[viewModelType];
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Finds the properties that represent a <see cref="PropertyData"/>.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns>The list of <see cref="PropertyData"/> elements found as properties.</returns>
        /// <exception cref="InvalidOperationException">One ore more properties are not declared correctly.</exception>
        private static IEnumerable<PropertyData> FindCatelProperties(Type type)
        {
            // Properties - safety checks for non-static properties
            var nonStaticProperties = (from property in type.GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(true, false, true))
                                       where property.PropertyType == typeof(PropertyData)
                                       select property).ToList();
            foreach (var nonStaticProperty in nonStaticProperties)
            {
                string error = string.Format("The property '{0}' of type 'PropertyData' declared as instance, but they can only be used as static", nonStaticProperty.Name);

                Log.Error(error);
                throw new InvalidOperationException(error);
            }

            // Properties - safety checks for non-public fields
            var nonPublicProperties = (from property in type.GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(true, true, true))
                                       where property.PropertyType == typeof(PropertyData) && !property.CanRead
                                       select property).ToList();
            foreach (var nonPublicProperty in nonPublicProperties)
            {
                string error = string.Format("The property '{0}' of type 'PropertyData' declared as non-public, but they can only be used as public", nonPublicProperty.Name);

                Log.Error(error);
                throw new InvalidOperationException(error);
            }

            // Properties - actual addition
            var foundProperties = new List<PropertyData>();

            var properties = new List<PropertyInfo>();
            properties.AddRange(type.GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(true, true, false)));
            foreach (var property in properties)
            {
                if (property.PropertyType == typeof(PropertyData))
                {
                    var propertyValue = property.GetValue(null, null) as PropertyData;
                    if (propertyValue != null)
                    {
                        foundProperties.Add(propertyValue);
                    }
                }
            }

            return foundProperties;
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Finds the non catel properties.
 /// </summary>
 /// <param name="type">The type.</param>
 /// <returns>The list of <see cref="PropertyInfo"/> elements found as properties.</returns>
 private static IEnumerable<PropertyInfo> FindNonCatelProperties(Type type)
 {
     return (from property in type.GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(true, false, true))
             where property.PropertyType != typeof(PropertyData)
             select property).ToList();
 }
        private void AddTypeMembers(Type type, XmlSerializerTypeInfo serializerTypeInfo)
        {
            var isModelBase = (type == typeof(ModelBase)) || typeof(ModelBase).IsAssignableFromEx(type);
            if (isModelBase)
            {
                var catelTypeInfo = PropertyDataManager.Default.GetCatelTypeInfo(type);
                var modelBaseProperties = catelTypeInfo.GetCatelProperties();
                foreach (var modelBaseProperty in modelBaseProperties)
                {
                    var propertyType = modelBaseProperty.Value.Type;
                    if (propertyType.FullName != null)
                    {
                        GetKnownTypes(propertyType, serializerTypeInfo);
                    }
                    else
                    {
                        serializerTypeInfo.AddTypeAsHandled(propertyType);
                    }
                }
            }
            else
            {
                bool allowNonPublicReflection = AllowNonPublicReflection(type);

                // Fields
                var fields = type.GetFieldsEx(BindingFlagsHelper.GetFinalBindingFlags(false, false, allowNonPublicReflection));
                foreach (var field in fields)
                {
                    var fieldType = field.FieldType;
                    if (fieldType.FullName != null)
                    {
                        GetKnownTypes(fieldType, serializerTypeInfo);
                    }
                    else
                    {
                        serializerTypeInfo.AddTypeAsHandled(fieldType);
                    }
                }

                // Properties
                var properties = type.GetPropertiesEx(BindingFlagsHelper.GetFinalBindingFlags(false, false, allowNonPublicReflection));
                foreach (var property in properties)
                {
                    var propertyType = property.PropertyType;
                    if (propertyType.FullName != null)
                    {
                        GetKnownTypes(propertyType, serializerTypeInfo);
                    }
                    else
                    {
                        serializerTypeInfo.AddTypeAsHandled(propertyType);
                    }
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Gets the properties to serialize for the specified object.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns>The list of properties to serialize.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="type"/> is <c>null</c>.</exception>
        public virtual HashSet<string> GetPropertiesToSerialize(Type type)
        {
            Argument.IsNotNull("type", type);

            return _propertiesToSerializeCache.GetFromCacheOrFetch(type, () =>
            {
                var properties = new List<string>();

                var propertyDataManager = PropertyDataManager.Default;
                var catelTypeInfo = propertyDataManager.GetCatelTypeInfo(type);
                var catelProperties = catelTypeInfo.GetCatelProperties();
                var catelPropertyNames = catelProperties.Keys.ToList();
                foreach (var modelProperty in catelProperties)
                {
                    var propertyData = modelProperty.Value;

                    if (!propertyData.IsSerializable)
                    {
                        Log.Warning("Property '{0}' is not serializable, so will be excluded from the serialization", propertyData.Name);
                        continue;
                    }

                    if (!propertyData.IncludeInSerialization)
                    {
                        Log.Debug("Property '{0}' is flagged to be excluded from serialization", propertyData.Name);
                        continue;
                    }

                    var propertyType = type.GetPropertyEx(modelProperty.Value.Name);
                    if (propertyType != null)
                    {
                        if (!AttributeHelper.IsDecoratedWithAttribute<ExcludeFromSerializationAttribute>(propertyType))
                        {
                            properties.Add(modelProperty.Key);
                        }
                    }
                    else
                    {
                        // Dynamic property, always include
                        properties.Add(modelProperty.Key);
                    }
                }

                var typeProperties = type.GetPropertiesEx();
                foreach (var typeProperty in typeProperties)
                {
                    if (!catelPropertyNames.Contains(typeProperty.Name))
                    {
                        if (AttributeHelper.IsDecoratedWithAttribute<IncludeInSerializationAttribute>(typeProperty))
                        {
                            properties.Add(typeProperty.Name);
                        }
                    }
                }

                return new HashSet<string>(properties);
            });
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Initializes the view model meta data.
        /// <para />
        /// This method only initializes the meta data once per view model type. If a type is already initialized,
        /// this method will immediately return.
        /// </summary>
        /// <param name="viewModelType">Type of the view model.</param>
        /// <returns>ViewModelMetadata.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="viewModelType" /> is <c>null</c>.</exception>
        private static ViewModelMetadata InitializeViewModelMetaData(Type viewModelType)
        {
            if (_metaData.ContainsKey(viewModelType))
            {
                return _metaData[viewModelType];
            }

            var properties = new List<PropertyInfo>();
            var bindingFlags = BindingFlagsHelper.GetFinalBindingFlags(true, false, true);
            properties.AddRange(viewModelType.GetPropertiesEx(bindingFlags));

            var modelObjectsInfo = new Dictionary<string, ModelInfo>();
            var viewModelToModelMap = new Dictionary<string, ViewModelToModelMapping>();
            var validationSummaries = new Dictionary<string, ValidationToViewModelAttribute>();

            foreach (var propertyInfo in properties)
            {
                #region Model attributes
                var modelAttribute = propertyInfo.GetCustomAttributeEx(typeof(ModelAttribute), true) as ModelAttribute;
                if (modelAttribute != null)
                {
                    modelObjectsInfo.Add(propertyInfo.Name, new ModelInfo(propertyInfo.Name, modelAttribute));
                }
                #endregion

                #region ViewModelToModel attributes
                var viewModelToModelAttribute = propertyInfo.GetCustomAttributeEx(typeof(ViewModelToModelAttribute), true) as ViewModelToModelAttribute;
                if (viewModelToModelAttribute != null)
                {
                    if (string.IsNullOrEmpty(viewModelToModelAttribute.Property))
                    {
                        // Assume the property name in the model is the same as in the view model
                        viewModelToModelAttribute.Property = propertyInfo.Name;
                    }

                    if (!viewModelToModelMap.ContainsKey(propertyInfo.Name))
                    {
                        viewModelToModelMap.Add(propertyInfo.Name, new ViewModelToModelMapping(propertyInfo.Name, viewModelToModelAttribute));
                    }
                }
                #endregion

                #region ValidationToViewModel attributes
                var validationToViewModelAttribute = propertyInfo.GetCustomAttributeEx(typeof(ValidationToViewModelAttribute), true) as ValidationToViewModelAttribute;
                if (validationToViewModelAttribute != null)
                {
                    if (propertyInfo.PropertyType != typeof(IValidationSummary))
                    {
                        throw Log.ErrorAndCreateException<InvalidOperationException>("A property decorated with the ValidationToViewModel attribute must be of type IValidationSummary, but '{0}' is not", propertyInfo.Name);
                    }

                    validationSummaries.Add(propertyInfo.Name, validationToViewModelAttribute);

                    Log.Debug("Registered property '{0}' as validation summary", propertyInfo.Name);
                }
                #endregion
            }

            _metaData.Add(viewModelType, new ViewModelMetadata(viewModelType, modelObjectsInfo, viewModelToModelMap, validationSummaries));

            return _metaData[viewModelType];
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Gets the regular properties.
        /// </summary>
        /// <param name="type">Type of the model.</param>
        /// <returns>A hash set containing the regular properties.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="type"/> is <c>null</c>.</exception>
        public Dictionary<string, MemberMetadata> GetRegularProperties(Type type)
        {
            Argument.IsNotNull("type", type);

            return _regularPropertiesCache.GetFromCacheOrFetch(type, () =>
            {
                var dictionary = new Dictionary<string, MemberMetadata>();

                var catelPropertyNames = GetCatelPropertyNames(type, true);

                var regularProperties = type.GetPropertiesEx();
                foreach (var propertyInfo in regularProperties)
                {
                    if (catelPropertyNames.Contains(propertyInfo.Name) ||
                        propertyInfo.DeclaringType == typeof(ModelBase))
                    {
                        continue;
                    }

                    var memberMetadata = new MemberMetadata(type, propertyInfo.PropertyType, SerializationMemberGroup.RegularProperty, propertyInfo.Name)
                    {
                        Tag = propertyInfo
                    };

                    var nameOverride = GetNameOverrideForSerialization(propertyInfo);
                    if (!string.IsNullOrWhiteSpace(nameOverride))
                    {
                        memberMetadata.MemberNameForSerialization = nameOverride;
                    }

                    dictionary[propertyInfo.Name] = memberMetadata;
                }

                return dictionary;
            });
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ViewModelCommandManager" /> class.
        /// </summary>
        /// <param name="viewModel">The view model.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="viewModel"/> is <c>null</c>.</exception>
        private ViewModelCommandManager(IViewModel viewModel)
        {
            Argument.IsNotNull("viewModel", viewModel);

            Log.Debug("Creating a ViewModelCommandManager for view model '{0}' with unique identifier '{1}'", viewModel.GetType().FullName, viewModel.UniqueIdentifier);

            _viewModel = viewModel;
            _viewModelType = viewModel.GetType();
            _viewModel.Initialized += OnViewModelInitialized;
            _viewModel.PropertyChanged += OnViewModelPropertyChanged;
            _viewModel.Closed += OnViewModelClosed;

            var properties = new List<PropertyInfo>();
            properties.AddRange(_viewModelType.GetPropertiesEx());

            foreach (var propertyInfo in properties)
            {
                if (propertyInfo.PropertyType.ImplementsInterfaceEx(typeof(ICommand)))
                {
                    _commandProperties.Add(propertyInfo);
                }
            }

            RegisterCommands(false);

            Log.Debug("Created a ViewModelCommandManager for view model '{0}' with unique identifier '{1}'", viewModel.GetType().FullName, viewModel.UniqueIdentifier);
        }
        private static MemberInfo TryFindMetaMemberInfo(Type metaType, MemberInfo member)
        {
            var flags = MemberFlags.Public | MemberFlags.NonPublic | MemberFlags.Instance;
            var property = member as PropertyInfo;
            if (property != null)
                return metaType
                    .GetPropertiesEx(flags)
                    .FirstOrDefault(
                        info =>
                            info.Name == property.Name &&
                            info.GetIndexParameters().SequenceEqual(property.GetIndexParameters()));
            var field = member as FieldInfo;
            if (field != null)
                return metaType.GetFieldEx(field.Name, flags);
            var method = member as MethodInfo;
            if (method != null)
                return metaType
                    .GetMethodsEx(flags)
                    .FirstOrDefault(info => info.Name == method.Name && info.ReturnType.Equals(method.ReturnType)
                                            &&
                                            info.GetParameters()
                                                .Select(parameterInfo => parameterInfo.ParameterType)
                                                .SequenceEqual(method.GetParameters().Select(parameterInfo => parameterInfo.ParameterType)));
            var eventInfo = member as EventInfo;
            if (eventInfo != null)
#if PCL_WINRT
                return metaType.GetRuntimeEvents().FirstOrDefault(info => info.Name == eventInfo.Name);
#else
                return metaType.GetEvents().FirstOrDefault(info => info.Name == eventInfo.Name);
#endif

            return null;
        }