private string GetTypeCacheKey(Type type, DynamicDtoTypeBuildingContext context)
        {
            var entityType = DynamicDtoExtensions.GetDynamicDtoEntityType(type);

            if (entityType == null)
            {
                throw new NotSupportedException($"Type '{type.FullName}' is not a dynamic DTO");
            }

            return($"{entityType.FullName}|formFields:{context.AddFormFieldsProperty.ToString().ToLower()}|useEntityDtos:{context.UseDtoForEntityReferences.ToString().ToLower()}");
        }
        public async Task <List <DynamicProperty> > GetDynamicPropertiesAsync(Type type, DynamicDtoTypeBuildingContext context)
        {
            var entityType = DynamicDtoExtensions.GetDynamicDtoEntityType(type);

            if (entityType == null)
            {
                throw new Exception("Failed to extract entity type of the dynamic DTO");
            }

            var properties = new DynamicPropertyList();

            var hardCodedDtoProperties = type.GetProperties().Select(p => p.Name.ToLower()).ToList();

            var configuredProperties = await GetEntityPropertiesAsync(entityType);

            foreach (var property in configuredProperties)
            {
                // skip property if already included into the DTO (hardcoded)
                if (hardCodedDtoProperties.Contains(property.Name.ToLower()))
                {
                    continue;
                }

                if (string.IsNullOrWhiteSpace(property.DataType))
                {
                    Logger.Warn($"Type '{type.FullName}': {nameof(property.DataType)} of property {property.Name} is empty");
                    continue;
                }

                var propertyType = await GetDtoPropertyTypeAsync(property, context);

                if (propertyType != null)
                {
                    properties.Add(property.Name, propertyType);
                }
            }

            // internal fields
            if (context.AddFormFieldsProperty)
            {
                properties.Add(nameof(IHasFormFieldsList._formFields), typeof(List <string>));
            }

            return(properties);
        }