public static async Task <PropertySelectorViewModel> Create(Document doc, string dtoName, SolutionLocation dtoLocation, Document existingDto = null)
        {
            var autogeneratedProperties = await EntityParser.GetAutoGeneratedProperties(existingDto);

            var instance = new PropertySelectorViewModel();

            instance.EntityModel = await EntityViewModel.CreateRecursive(doc, depth : 3, existingProperties : autogeneratedProperties, canReuseBaseMapper : true);

            instance.EntityModel.DtoName = dtoName;
            instance.DtoLocation         = dtoLocation;

            var isDerived = await EntityParser.HasBaseDto(existingDto, instance.EntityModel.BaseEntityDtoName);

            instance.EntityModel.ReuseBaseEntityMapper |= isDerived;

            instance.AddDataContract = await EntityParser.HasDataContract(existingDto);

            instance.AddDataAnnotations = await EntityParser.HasDataAnnotations(existingDto);

            return(instance);
        }
 public PropertyViewModel(EntityViewModel entityModel)
 {
     this._entityViewModel = entityModel;
 }
        public static async Task <EntityViewModel> CreateRecursive(Document doc, int depth = 3, bool autoSelect = true, bool canSelectCollections = true, List <string> existingProperties = null, bool canReuseBaseMapper = false)
        {
            var instance = new EntityViewModel();

            instance.Properties = new ObservableCollection <PropertyViewModel>();

            instance._originalMetadata = await EntityParser.FromDocument(doc, includeInherited : true);

            instance.EntityName = instance._originalMetadata.Name;

            foreach (var p in instance._originalMetadata.Properties)
            {
                var propViewModel = new PropertyViewModel(instance);
                propViewModel.Name        = p.Name;
                propViewModel.IsInherited = p.IsInherited;
                propViewModel.IsVisible   = true;
                propViewModel.Type        = p.Type;
                propViewModel.CanSelect   = true;

                if (p.IsCollection && !canSelectCollections)
                {
                    propViewModel.CanSelect = false;
                }

                propViewModel.IsSelected = autoSelect && p.IsSimpleProperty;

                if (existingProperties != null)
                {
                    propViewModel.IsSelected = propViewModel.CanSelect && existingProperties.Any(x => x == p.Name);
                }

                if (p.IsRelation && !p.IsCollection && depth > 0)
                {
                    var relatedDoc = await doc.GetRelatedEntityDocument(p.RelatedEntityName);

                    if (relatedDoc != null)
                    {
                        var relatedProperties = existingProperties == null
                            ? null
                            : existingProperties.Where(x => x.StartsWith(p.Name))
                                                .Where(x => !instance._originalMetadata.Properties.Any(o => o.Name == x))
                                                .Select(x => x.Substring(p.Name.Length))
                                                .ToList();

                        propViewModel.RelatedEntity = await CreateRecursive(relatedDoc, depth : depth - 1, autoSelect : false, canSelectCollections : false, existingProperties : relatedProperties);
                    }
                    else
                    {
                        p.IsRelation       = false;
                        p.IsSimpleProperty = true;
                    }
                }

                instance.Properties.Add(propViewModel);
            }

            if (canReuseBaseMapper && !string.IsNullOrWhiteSpace(instance._originalMetadata.BaseClassDtoName))
            {
                instance.CanReuseBaseMapper = true;
                instance.BaseEntityDtoName  = instance._originalMetadata.BaseClassDtoName;

                if (existingProperties == null)
                {
                    instance.ReuseBaseEntityMapper = true;
                }
            }

            return(instance);
        }