private static bool AssignEntitiesToMembers()

in Cognitive Services/CSharp/Library/LuisActionBinding/LuisActionResolver.cs [548:677]


        private static bool AssignEntitiesToMembers(
            ILuisAction action,
            IEnumerable<PropertyInfo> properties,
            IEnumerable<EntityRecommendation> entities,
            Func<PropertyInfo, IEnumerable<EntityRecommendation>, EntityRecommendation> entityExtractor = null)
        {
            var result = true;

            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            if (properties == null)
            {
                throw new ArgumentNullException(nameof(properties));
            }

            if (entities == null)
            {
                throw new ArgumentNullException(nameof(entities));
            }

            if (!entities.Any())
            {
                return !result;
            }

            // Cross match entities to copy resolution values for custom entities from pairs
            foreach (var group in entities.GroupBy(e => e.Entity))
            {
                if (group.Count() > 1)
                {
                    var entityToUpdate = group.FirstOrDefault(e => !BuiltInTypes.IsBuiltInType(e.Type));
                    var entityWithValue = group.FirstOrDefault(e => e.Resolution != null);
                    if (entityToUpdate != null && entityWithValue != null)
                    {
                        entityToUpdate.Resolution = entityWithValue.Resolution;
                    }
                }
            }

            foreach (var property in properties)
            {
                var matchingEntity = default(EntityRecommendation);
                var matchingEntities = default(IEnumerable<EntityRecommendation>);

                // Find using custom type from attrib if available
                var paramAttrib = property.GetCustomAttributes<LuisActionBindingParamAttribute>(true).FirstOrDefault();
                if (paramAttrib != null)
                {
                    matchingEntities = entities.Where(e => e.Type == paramAttrib.CustomType);
                }

                // Find using property name
                if (matchingEntities == null || !matchingEntities.Any())
                {
                    matchingEntities = entities.Where(e => e.Type == property.Name);
                }

                // Find using builtin type from attrib if available
                if ((matchingEntities == null || !matchingEntities.Any()) && paramAttrib != null)
                {
                    matchingEntities = entities.Where(e => e.Type == paramAttrib.BuiltinType);
                }

                // If callback available then use it
                if (matchingEntities.Count() > 1)
                {
                    if (entityExtractor != null)
                    {
                        matchingEntity = entityExtractor(property, matchingEntities);
                    }
                }
                else
                {
                    matchingEntity = matchingEntities.FirstOrDefault();
                }

                // Prioritize resolution
                if (matchingEntity != null)
                {
                    object paramValue = null;
                    if (matchingEntity.Resolution != null && matchingEntity.Resolution.Count > 0)
                    {
                        var resolutionValue = matchingEntity.Resolution.First().Value;
                        if (resolutionValue is IList<object>)
                        {
                            // multiple resolution values - datetimev2
                            var dateTimeResolutionValues = GetDateTimeValues(matchingEntity);
                            paramValue = dateTimeResolutionValues["value"];
                        }

                        if (paramValue == null)
                        {
                            // other built-in with single resolution value
                            paramValue = resolutionValue;
                        }
                    }
                    else
                    {
                        paramValue = matchingEntity.Entity;
                    }

                    result &= AssignValue(action, property, paramValue);
                }
                else if (matchingEntities.Count() > 0
                    && matchingEntities.Count(e => e.Resolution != null && e.Resolution.First().Value is JArray) == matchingEntities.Count())
                {
                    var paramValues = new JArray();

                    foreach (var currentMatchingEntity in matchingEntities)
                    {
                        var values = currentMatchingEntity.Resolution.First().Value as JArray;
                        foreach (var value in values)
                        {
                            paramValues.Add(value);
                        }
                    }

                    result &= AssignValue(action, property, paramValues);
                }
                else
                {
                    result = false;
                }
            }

            return result;
        }