public static TemplateDomain ConvertToDomain(this TemplateDTO templateDTO)
        {
            var templateDomain = new TemplateDomain();

            //Map the template
            templateDomain.InjectFrom(templateDTO);
            templateDomain.InjectFrom <MapEnum>(new { TemplateType = templateDTO.TemplateType });

            //Map the version
            templateDomain.TemplateVersions.InjectFrom <TemplateVersionDTO, TemplateVersionDomain>(templateDTO.TemplateVersionsDTOs);

            //Map the sections
            templateDomain.TemplateVersions.ForEach(tv =>
            {
                //id is already mapped before, so we can get the matching dto for the domain.
                TemplateVersionDTO matchedTemplateVersionDTOs = templateDTO.TemplateVersionsDTOs.SingleOrDefault(x => x.Id == tv.Id);

                if (matchedTemplateVersionDTOs != null)
                {
                    var sectionDomains = tv.Sections.InjectFrom <SectionDTO, SectionDomain>(matchedTemplateVersionDTOs.Sections);

                    sectionDomains.ForEach(sd =>
                    {
                        SectionDTO sectionDTO = matchedTemplateVersionDTOs.Sections.SingleOrDefault(x => x.Id == sd.Id);

                        if (sectionDTO != null)
                        {
                            var sectionQuestion = (SectionQuestionDomain)sd.SectionQuestion.InjectFrom(sectionDTO.SectionQuestionDTO);
                            List <QuestionDomain> questionDomains = sectionQuestion.Questions.InjectFrom <QuestionDTO, QuestionDomain>(sectionDTO.SectionQuestionDTO.Questions);

                            questionDomains.ForEach(domain =>
                            {
                                QuestionDTO questionDTO = sectionDTO.SectionQuestionDTO.Questions.SingleOrDefault(x => x.Id == domain.Id);

                                if (questionDTO != null)
                                {
                                    domain.InjectFrom <MapEnum>(new { QuestionType = questionDTO.QuestionTypeDTO });
                                }
                            });
                        }
                    });
                }
            });

            return(templateDomain);
        }
        public void ResoveNestedCollections_MapToDifferentEntity_ConvertToDomain()
        {
            var originalTemplateDTO = OriginalTemplate();

            TemplateDomain templateDomain = originalTemplateDTO.ConvertToDomain();

            //Template Map
            Assert.AreEqual(originalTemplateDTO.Name, templateDomain.Name);
            Assert.AreEqual(originalTemplateDTO.TemplateType.ToString(), templateDomain.TemplateType.ToString());

            //Nested collection: Template->TemplateVerion1 Map
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(0).Name, templateDomain.TemplateVersions.ElementAt(0).Name);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(0).Number, templateDomain.TemplateVersions.ElementAt(0).Number);

            //Nested collection: Template->TemplateVerion2 Map
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Name, templateDomain.TemplateVersions.ElementAt(1).Name);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Number, templateDomain.TemplateVersions.ElementAt(1).Number);

            //Nested collection: Template->TemplateVerion1->Section1 Map
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(0).Sections.ElementAt(0).Name, templateDomain.TemplateVersions.ElementAt(0).Sections.ElementAt(0).Name);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(0).Sections.ElementAt(0).Id, templateDomain.TemplateVersions.ElementAt(0).Sections.ElementAt(0).Id);

            //Nested collection: Template->TemplateVerion2->Section1 Map
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Sections.ElementAt(0).Name, templateDomain.TemplateVersions.ElementAt(1).Sections.ElementAt(0).Name);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Sections.ElementAt(0).Id, templateDomain.TemplateVersions.ElementAt(1).Sections.ElementAt(0).Id);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Sections.ElementAt(1).Name, templateDomain.TemplateVersions.ElementAt(1).Sections.ElementAt(1).Name);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Sections.ElementAt(1).Id, templateDomain.TemplateVersions.ElementAt(1).Sections.ElementAt(1).Id);


            //Nested collection: Template->TemplateVerion1->Section1-> SectionQuestion1 Map
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(0).Sections.ElementAt(0).SectionQuestionDTO.Name, templateDomain.TemplateVersions.ElementAt(0).Sections.ElementAt(0).SectionQuestion.Name);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(0).Sections.ElementAt(0).SectionQuestionDTO.Id, templateDomain.TemplateVersions.ElementAt(0).Sections.ElementAt(0).SectionQuestion.Id);

            //Nested collection: Template->TemplateVerion2->Section1-> SectionQuestion Map
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Sections.ElementAt(0).SectionQuestionDTO.Name, templateDomain.TemplateVersions.ElementAt(1).Sections.ElementAt(0).SectionQuestion.Name);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Sections.ElementAt(0).SectionQuestionDTO.Id, templateDomain.TemplateVersions.ElementAt(1).Sections.ElementAt(0).SectionQuestion.Id);

            //Nested collection: Template->TemplateVerion2->Section2-> SectionQuestion Map
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Sections.ElementAt(1).SectionQuestionDTO.Name, templateDomain.TemplateVersions.ElementAt(1).Sections.ElementAt(1).SectionQuestion.Name);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Sections.ElementAt(1).SectionQuestionDTO.Id, templateDomain.TemplateVersions.ElementAt(1).Sections.ElementAt(1).SectionQuestion.Id);

            //TODO: questions
            //Nested collection: Template->TemplateVerion1->Section1-> SectionQuestion1->Question1 Map
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(0).Sections.ElementAt(0).SectionQuestionDTO.Questions.ElementAt(0).Text, templateDomain.TemplateVersions.ElementAt(0).Sections.ElementAt(0).SectionQuestion.Questions.ElementAt(0).Text);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(0).Sections.ElementAt(0).SectionQuestionDTO.Questions.ElementAt(0).Id, templateDomain.TemplateVersions.ElementAt(0).Sections.ElementAt(0).SectionQuestion.Questions.ElementAt(0).Id);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(0).Sections.ElementAt(0).SectionQuestionDTO.Questions.ElementAt(0).QuestionTypeDTO.ToString(), templateDomain.TemplateVersions.ElementAt(0).Sections.ElementAt(0).SectionQuestion.Questions.ElementAt(0).QuestionType.ToString());

            //Nested collection: Template->TemplateVerion1->Section1-> SectionQuestion1->Question2 Map
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(0).Sections.ElementAt(0).SectionQuestionDTO.Questions.ElementAt(1).Text, templateDomain.TemplateVersions.ElementAt(0).Sections.ElementAt(0).SectionQuestion.Questions.ElementAt(1).Text);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(0).Sections.ElementAt(0).SectionQuestionDTO.Questions.ElementAt(1).Id, templateDomain.TemplateVersions.ElementAt(0).Sections.ElementAt(0).SectionQuestion.Questions.ElementAt(1).Id);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(0).Sections.ElementAt(0).SectionQuestionDTO.Questions.ElementAt(1).QuestionTypeDTO.ToString(), templateDomain.TemplateVersions.ElementAt(0).Sections.ElementAt(0).SectionQuestion.Questions.ElementAt(1).QuestionType.ToString());

            //Nested collection: Template->TemplateVerion2->Section1-> SectionQuestion1->Question1 Map
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Sections.ElementAt(0).SectionQuestionDTO.Questions.ElementAt(0).Text, templateDomain.TemplateVersions.ElementAt(1).Sections.ElementAt(0).SectionQuestion.Questions.ElementAt(0).Text);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Sections.ElementAt(0).SectionQuestionDTO.Questions.ElementAt(0).Id, templateDomain.TemplateVersions.ElementAt(1).Sections.ElementAt(0).SectionQuestion.Questions.ElementAt(0).Id);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Sections.ElementAt(0).SectionQuestionDTO.Questions.ElementAt(0).QuestionTypeDTO.ToString(), templateDomain.TemplateVersions.ElementAt(1).Sections.ElementAt(0).SectionQuestion.Questions.ElementAt(0).QuestionType.ToString());

            //Nested collection: Template->TemplateVerion2->Section2-> SectionQuestion1->Question1 Map
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Sections.ElementAt(1).SectionQuestionDTO.Questions.ElementAt(0).Text, templateDomain.TemplateVersions.ElementAt(1).Sections.ElementAt(1).SectionQuestion.Questions.ElementAt(0).Text);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Sections.ElementAt(1).SectionQuestionDTO.Questions.ElementAt(0).Id, templateDomain.TemplateVersions.ElementAt(1).Sections.ElementAt(1).SectionQuestion.Questions.ElementAt(0).Id);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Sections.ElementAt(1).SectionQuestionDTO.Questions.ElementAt(0).QuestionTypeDTO.ToString(), templateDomain.TemplateVersions.ElementAt(1).Sections.ElementAt(1).SectionQuestion.Questions.ElementAt(0).QuestionType.ToString());

            //Nested collection: Template->TemplateVerion2->Section2-> SectionQuestion1->Question2 Map
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Sections.ElementAt(1).SectionQuestionDTO.Questions.ElementAt(1).Text, templateDomain.TemplateVersions.ElementAt(1).Sections.ElementAt(1).SectionQuestion.Questions.ElementAt(1).Text);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Sections.ElementAt(1).SectionQuestionDTO.Questions.ElementAt(1).Id, templateDomain.TemplateVersions.ElementAt(1).Sections.ElementAt(1).SectionQuestion.Questions.ElementAt(1).Id);
            Assert.AreEqual(originalTemplateDTO.TemplateVersionsDTOs.ElementAt(1).Sections.ElementAt(1).SectionQuestionDTO.Questions.ElementAt(1).QuestionTypeDTO.ToString(), templateDomain.TemplateVersions.ElementAt(1).Sections.ElementAt(1).SectionQuestion.Questions.ElementAt(1).QuestionType.ToString());
        }
        public static TemplateDomain ConvertToDomain(this TemplateDTO templateDTO)
        {
            var templateDomain = new TemplateDomain();

            //Map the template
            templateDomain.InjectFrom(templateDTO);
            templateDomain.InjectFrom<MapEnum>(new { TemplateType = templateDTO.TemplateType });

            //Map the version
            templateDomain.TemplateVersions.InjectFrom<TemplateVersionDTO, TemplateVersionDomain>(templateDTO.TemplateVersionsDTOs);

            //Map the sections
            templateDomain.TemplateVersions.ForEach(tv =>
            {
                //id is already mapped before, so we can get the matching dto for the domain.
                TemplateVersionDTO matchedTemplateVersionDTOs = templateDTO.TemplateVersionsDTOs.SingleOrDefault(x => x.Id == tv.Id);

                if (matchedTemplateVersionDTOs != null)
                {
                    var sectionDomains = tv.Sections.InjectFrom<SectionDTO, SectionDomain>(matchedTemplateVersionDTOs.Sections);

                    sectionDomains.ForEach(sd =>
                    {
                        SectionDTO sectionDTO = matchedTemplateVersionDTOs.Sections.SingleOrDefault(x => x.Id == sd.Id);

                        if (sectionDTO != null)
                        {
                            var sectionQuestion = (SectionQuestionDomain)sd.SectionQuestion.InjectFrom(sectionDTO.SectionQuestionDTO);
                            List<QuestionDomain> questionDomains = sectionQuestion.Questions.InjectFrom<QuestionDTO, QuestionDomain>(sectionDTO.SectionQuestionDTO.Questions);

                            questionDomains.ForEach(domain =>
                            {
                                QuestionDTO questionDTO = sectionDTO.SectionQuestionDTO.Questions.SingleOrDefault(x => x.Id == domain.Id);

                                if (questionDTO != null)
                                {
                                    domain.InjectFrom<MapEnum>(new { QuestionType = questionDTO.QuestionTypeDTO });
                                }
                            });
                        }

                    });
                }
            });

            return templateDomain;
        }