Example #1
0
        /// <summary>
        /// When a complex property on this instance changes, this method performs
        /// the necessary attach/detach operations for the new instance.
        /// </summary>
        /// <param name="metaMember">The complex member.</param>
        private void AttachComplexObjectInstance(MetaMember metaMember)
        {
            // First check if the parent has an existing instance attached for this
            // property and detach if necessary.
            string memberName = metaMember.Member.Name;
            ComplexObject prevInstance = null;
            if (this.TrackedInstances.TryGetValue(memberName, out prevInstance))
            {
                prevInstance.Detach();
                this.TrackedInstances.Remove(memberName);
            }

            ComplexObject newInstance = (ComplexObject)metaMember.GetValue(this);
            if (newInstance != null)
            {
                // Attach to the new instance
                newInstance.Attach(this, memberName, this.OnDataMemberChanging, this.OnDataMemberChanged, this.OnMemberValidationChanged);
                this.TrackedInstances[memberName] = newInstance;

                // If the instance has validation errors, we need to sync them into our parent. This
                // needs to be done as a merge operation, since the parent may already have property
                // level errors for this member that must be retained.
                if (newInstance.HasValidationErrors)
                {
                    foreach (ValidationResult error in ValidationUtilities.ApplyMemberPath(newInstance.ValidationErrors, memberName))
                    {
                        this.ValidationResultCollection.Add(error);
                    }
                }
            }
        }
        private MetaType(Type type)
        {
            IEnumerable<PropertyInfo> properties = type.GetProperties(MemberBindingFlags).Where(p => p.GetIndexParameters().Length == 0).OrderBy(p => p.Name);

            this._isComplex = TypeUtility.IsComplexType(type);

            bool hasOtherRoundtripMembers = false;
            foreach (PropertyInfo property in properties)
            {
                MetaMember metaMember = new MetaMember(this, property);
                metaMember.IsCollection = TypeUtility.IsSupportedCollectionType(property.PropertyType);
                if ((property.GetGetMethod() != null) && (property.GetSetMethod() != null))
                {
                    bool isPredefinedType = TypeUtility.IsPredefinedType(property.PropertyType);
                    bool isComplex = TypeUtility.IsSupportedComplexType(property.PropertyType);
                    metaMember.IsDataMember = isPredefinedType || isComplex;
                    metaMember.IsComplex = isComplex;

                    if (isComplex)
                    {
                        this._hasComplexMembers = true;
                    }
                }

                if (property.GetGetMethod() != null)
                {
                    metaMember.RequiresValidation = property.GetCustomAttributes(typeof(ValidationAttribute), true).Length > 0;
                }

                if (property.GetCustomAttributes(typeof(AssociationAttribute), false).Length > 0)
                {
                    metaMember.IsAssociationMember = true;
                }

                bool isKeyMember = property.GetCustomAttributes(typeof(KeyAttribute), false).Length > 0;
                if (isKeyMember)
                {
                    metaMember.IsKeyMember = true;
                }

                if (property.GetCustomAttributes(typeof(CompositionAttribute), false).Length > 0)
                {
                    this._hasComposition = true;
                }

                if (MetaType.IsRoundtripMember(metaMember))
                {
                    if (property.GetCustomAttributes(typeof(TimestampAttribute), false).Length != 0 &&
                        property.GetCustomAttributes(typeof(ConcurrencyCheckAttribute), false).Length != 0)
                    {
                        // Look for a concurrency version member. There should be only one
                        // (DomainService validation ensures this).
                        this._versionMember = metaMember;
                    }
                    else if (!isKeyMember)
                    {
                        // Look for non-key, non-timestamp roundtripped members. We can skip key members,
                        // since they're read only and cannot be modified by the client anyways.
                        hasOtherRoundtripMembers = true;
                    }
                    metaMember.IsRoundtripMember = true;
                }

                metaMember.EditableAttribute = (EditableAttribute)property.GetCustomAttributes(typeof(EditableAttribute), false).SingleOrDefault();
                this._metaMembers.Add(property.Name, metaMember);
            }

            if ((this._versionMember != null) && !hasOtherRoundtripMembers)
            {
                this._shouldRoundtripOriginal = false;
            }
            else
            {
                this._shouldRoundtripOriginal = true;
            }

            if (this._hasComposition)
            {
                this._childTypes = type
                        .GetProperties(MemberBindingFlags)
                        .Where(p => p.GetCustomAttributes(typeof(CompositionAttribute), false).Any())
                        .Select(p => TypeUtility.GetElementType(p.PropertyType)).ToArray();
            }

            this._type = type;

            this.CalculateAttributesRecursive(type, new HashSet<Type>());
        }
Example #3
0
 private static bool IsMergeableMember(MetaMember metaMember)
 {
     return metaMember.IsDataMember && !metaMember.IsAssociationMember &&
            (metaMember.Member.GetCustomAttributes(typeof (MergeAttribute), true).Length == 0 ||
            ((MergeAttribute)metaMember.Member.GetCustomAttributes(typeof (MergeAttribute), true).GetValue(0)).IsMergeable);
 }
        private static bool IsRoundtripMember(MetaMember metaMember)
        {
            bool isRoundtripEntity = metaMember.Member.DeclaringType.GetCustomAttributes(typeof(RoundtripOriginalAttribute), true).Length > 0;

            return metaMember.IsDataMember && !metaMember.IsAssociationMember &&
                       (isRoundtripEntity || metaMember.Member.GetCustomAttributes(typeof(RoundtripOriginalAttribute), false).Length != 0);
        }
Example #5
0
 /// <summary>
 /// Visit the specified <see cref="IEntityCollection"/>.
 /// </summary>
 /// <param name="entityCollection">The <see cref="IEntityCollection"/>.</param>
 /// <param name="member">The <see cref="MetaMember"/> for the collection member.</param>
 protected virtual void VisitEntityCollection(IEntityCollection entityCollection, MetaMember member)
 {
 }