public static bool IsEntity(this Expression expression, EntityService entityService)
 {
     return(entityService.ContainsEntityType(expression.Type));
 }
Exemplo n.º 2
0
        internal static bool ResolveEntityProperties(IList <JsonProperty> jsonProperties,
                                                     Type entityType, EntityTypeInfo entityTypeInfo,
                                                     EntityService entityService, DefaultContractResolver resolver,
                                                     Func <PropertyInfo, JsonProperty> createPropertyFunc)
        {
            if (entityService.ContainsEntityType(entityType))
            {
                if (jsonProperties.Any(jp => jp.PropertyName == Defaults.MetadataPropertyName &&
                                       jp.UnderlyingName == Defaults.DummyMetadataPropertyInfo.Name))
                {
                    return(false); //if we ever find the metadata property there, assume it has been resolved.
                }
                var _properties = new JsonPropertyCollection(entityType);

                var isComplex          = entityType.IsComplex();
                var propertiesToIgnore = entityTypeInfo.PropertiesToIgnore.ToArray();

                foreach (var jsonProp in jsonProperties)
                {
                    if (isComplex)
                    {
                        jsonProp.NullValueHandling    = NullValueHandling.Include; //we need null values for complex types
                        jsonProp.DefaultValueHandling =
                            DefaultValueHandling.Include;                          //we need all properties serialized
                    }

                    if (!jsonProp.Ignored &&
                        propertiesToIgnore.Any(np => np.Name == jsonProp.UnderlyingName))
                    {
                        jsonProp.Ignored = true;
                    }

                    _properties.Add(jsonProp);
                }

                lock (entityTypeInfo)
                {
                    //check for complextypes
                    var complexTypedProperties = entityTypeInfo.ComplexTypedProperties;

                    var complexJsonProperties = new List <JsonProperty>();

                    if (complexTypedProperties?.Count > 0)
                    {
                        //filter to complexproperties
                        var filteredJsonProperties = _properties?
                                                     .Select(p => new
                        {
                            JsonProperty = p,
                            PropertyInfo = complexTypedProperties.Where(pi => pi.Name == p.UnderlyingName)
                                           .FirstOrDefault()
                        })
                                                     .Where(np => np.PropertyInfo != null)
                                                     .ToDictionary(np => np.JsonProperty, np => np.PropertyInfo);

                        Func <Type, IList <JsonProperty> > getResolvedPropertiesFunc = t =>
                        {
                            var contract = resolver.ResolveContract(t) as JsonObjectContract;

                            if (contract.Properties?.Count > 0)
                            {
                                ResolveEntityProperties
                                    (contract.Properties, t, entityService.GetEntityTypeInfo(t),
                                    entityService, resolver, createPropertyFunc);
                            }

                            return(contract.Properties);
                        };

                        //generate new properties with new names for the complex types
                        foreach (var complexTypedJsonProp in filteredJsonProperties)
                        {
                            //get the complexTypedProperty's own jsonproperties
                            //include derived classes
                            var derivedTypes = entityService
                                               .GetDerivedEntityTypes(complexTypedJsonProp.Key.PropertyType)?
                                               .Where(t => t.IsComplex()).ToList();

                            if (derivedTypes == null || derivedTypes.Count == 0)
                            {
                                entityService.AddEntityType(complexTypedJsonProp.Key.PropertyType);
                                derivedTypes = new List <Type> {
                                    complexTypedJsonProp.Key.PropertyType
                                };
                            }

                            var childProperties = derivedTypes
                                                  .SelectMany(dt =>
                                                              getResolvedPropertiesFunc(dt)?.Where
                                                                  (p => /*!p.Ignored &&*/ p.PropertyName != Defaults.MetadataPropertyName) ??
                                                              new JsonProperty[0],
                                                              (dt, property) => new
                            {
                                DerivedType = dt,
                                Property    = property
                            })
                                                  .Where(jp => jp.Property != null)
                                                  .GroupBy(jp => jp.Property.PropertyName)
                                                  .Select(jpg => jpg.FirstOrDefault())
                                                  .ToList();

                            foreach (var childProp in childProperties)
                            {
                                //add the child to this type's properties
                                try
                                {
                                    var newChildProp = GetComplexTypedPropertyChild
                                                           (childProp.DerivedType, complexTypedJsonProp.Key,
                                                           complexTypedJsonProp.Value, childProp.Property);

                                    _properties.AddProperty(newChildProp);
                                    complexJsonProperties.Add(newChildProp);
                                }
                                catch (JsonSerializationException e)
                                {
                                    //for some reason member already exists and is duplicate
                                }
                            }

                            //ignore all complex typed properties
                            complexTypedJsonProp.Key.Ignored = true;
                        }
                    }

                    var nextIdx = -1;

                    //clear and re-add these properties
                    jsonProperties.Clear();

                    var orderedProperties = _properties.OrderBy(p => p.Order ?? nextIdx++);

                    foreach (var prop in orderedProperties)
                    {
                        jsonProperties.Add(prop);
                    }

                    //create metadata property and add it last
                    var metadataJsonProperty = createPropertyFunc(Defaults.DummyMetadataPropertyInfo);
                    metadataJsonProperty.PropertyName    = Defaults.MetadataPropertyName;
                    metadataJsonProperty.ValueProvider   = new MetadataValueProvider(entityType, complexJsonProperties);
                    metadataJsonProperty.ShouldSerialize = instance =>
                    {
                        return(!(metadataJsonProperty.ValueProvider as MetadataValueProvider)
                               .BuildMetadata(instance).IsEmpty());
                    };
                    metadataJsonProperty.Order = int.MaxValue; //try to make it the last serialized

                    jsonProperties.Add(metadataJsonProperty);

                    //assign and resolve these properties
                    entityTypeInfo.JsonProperties = new List <JsonProperty>(jsonProperties);

                    return(true);
                }
            }

            return(false);
        }