Example #1
0
        public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
        {
            if (objectType == null && instance != null)
            {
                objectType = instance.GetType();
            }

            if (this._type != objectType)
            {
                // In inheritance scenarios, we might be called to provide a descriptor
                // for a derived Type. In that case, we just return base.
                return(base.GetTypeDescriptor(objectType, instance));
            }

            if (this._customTypeDescriptor == null)
            {
                // CLR, buddy class type descriptors
                this._customTypeDescriptor = base.GetTypeDescriptor(objectType, instance);

                // EF, any other custom type descriptors provided through DomainServiceDescriptionProviders.
                this._customTypeDescriptor = this._descriptionProvider.GetTypeDescriptor(objectType, this._customTypeDescriptor);

                // initialize FK members AFTER our type descriptors have chained
                HashSet <string> foreignKeyMembers = this.GetForeignKeyMembers();

                // if any FK member of any association is also part of the primary key, then the key cannot be marked
                // Editable(false)
                bool keyIsEditable = false;
                foreach (PropertyDescriptor pd in this._customTypeDescriptor.GetProperties())
                {
                    if (pd.Attributes[typeof(KeyAttribute)] != null &&
                        foreignKeyMembers.Contains(pd.Name))
                    {
                        keyIsEditable = true;
                        break;
                    }
                }

                if (DomainTypeDescriptor.ShouldRegister(this._customTypeDescriptor, keyIsEditable, foreignKeyMembers))
                {
                    // Extend the chain with one more descriptor.
                    this._customTypeDescriptor = new DomainTypeDescriptor(objectType, this._customTypeDescriptor, keyIsEditable, foreignKeyMembers);
                }
            }

            return(this._customTypeDescriptor);
        }
        private ICollection <PropertyDescriptor> CreateProjectionProperties(IEnumerable <PropertyDescriptor> existingProperties)
        {
            // Get the map of projection includes for each property
            List <PropertyDescriptor> projectionProperties = new List <PropertyDescriptor>();
            Dictionary <PropertyDescriptor, IncludeAttribute[]> includeMap = DomainTypeDescriptor.GetProjectionIncludeMap(this._entityType, existingProperties);

            if (includeMap.Count == 0)
            {
                return(projectionProperties);
            }

            // for each existing property add projection properties for any member projections
            foreach (PropertyDescriptor pd in existingProperties)
            {
                IncludeAttribute[] memberProjections;
                includeMap.TryGetValue(pd, out memberProjections);
                if (memberProjections == null)
                {
                    // no member projections for this property
                    continue;
                }

                foreach (IncludeAttribute memberProjection in memberProjections)
                {
                    // If the projection member already exists as a property on the source type
                    // skip, otherwise we'll generate a duplicate
                    if (existingProperties.SingleOrDefault(p => p.Name == memberProjection.MemberName) != null)
                    {
                        continue;
                    }

                    // Drill through the projection path to get the target property
                    PropertyDescriptor targetProperty = pd;
                    foreach (string pathMember in memberProjection.Path.Split('.'))
                    {
                        if (targetProperty.PropertyType == this._entityType)
                        {
                            // avoid recursion
                            targetProperty = existingProperties.SingleOrDefault(p => p.Name == pathMember);
                        }
                        else
                        {
                            targetProperty = TypeDescriptor.GetProperties(targetProperty.PropertyType)[pathMember];
                        }

                        if (targetProperty == null)
                        {
                            throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resource.InvalidMemberProjection_Path, memberProjection.Path, pd.PropertyType, pd.Name));
                        }
                    }

                    // verify the projected type is a supported type
                    if (!TypeUtility.IsPredefinedType(targetProperty.PropertyType))
                    {
                        throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resource.InvalidMemberProjection_InvalidProjectedType, targetProperty.ComponentType, targetProperty.Name, pd.PropertyType, pd.Name));
                    }

                    // add the virtual projection property
                    projectionProperties.Add(new MemberProjectionPropertyDescriptor(pd, targetProperty, memberProjection));
                }
            }

            return(projectionProperties);
        }