public void ShoulImplicitConvertToExpression() { var spec = new GenericSpecification<User>(user => user.IsMale); Expression<Func<User, bool>> expression = spec; Assert.NotNull(expression); }
public IReadOnlyList <MovieDto> GetAllMovies(bool onlyForChildren, decimal minimumRating, bool availableOnCd) { // how to combine expressions? var specification = new GenericSpecification <MovieMiddle>(MovieMiddle.IsSuitableForChildren); return((IReadOnlyList <MovieDto>)repository.GetAllMovies(specification).Select(m => new MovieDto())); }
public void ShouldNegateExpression() { var spec = new GenericSpecification<User>(user => user.IsMale); var result = new UserRepository().Where(!spec).Single(); Assert.Equal("Maria Lucia", result.Name); }
public void ShoulImplicitConvertToFunc() { var spec = new GenericSpecification<User>(user => user.IsMale); Func<User, bool> func = spec; Assert.NotNull(func); }
public async Task <TEntity> FindAsync(ISpecification <TEntity> specification) { GenericSpecification <TEntity> genericSpecification = specification as GenericSpecification <TEntity>; FeedIterator <TEntity> iterator = null; if (genericSpecification.OrderBy == null) { iterator = this._container.GetItemLinqQueryable <TEntity>().Where(specification.Predicate).ToFeedIterator(); } else if (genericSpecification.Order == Order.Asc) { iterator = this._container.GetItemLinqQueryable <TEntity>().Where(specification.Predicate).OrderBy(specification.OrderBy).ToFeedIterator(); } else if (genericSpecification.Order == Order.Desc) { iterator = this._container.GetItemLinqQueryable <TEntity>().Where(specification.Predicate).OrderByDescending(specification.OrderBy).ToFeedIterator(); } if (iterator.HasMoreResults) { return((await iterator.ReadNextAsync()).FirstOrDefault()); } else { return(null); } }
public IEnumerable<Product> GetPopularKeyboards() { var keyboard = new GenericSpecification<Product>(product=>product.Category==ProductCategory.KeyBoard); var popular = new GenericSpecification<Product>(p=>p.AverageRatings>4); var popularKeyboard = popular.And(keyboard); return _repository.Get(popularKeyboard); }
public ProdutoConsistenteValidation() { var NomeProduto = new GenericSpecification <Produto>(p => !string.IsNullOrWhiteSpace(p.Nome)); var CategoriaProduto = new GenericSpecification <Produto>(p => p.CategoriaId != null); Add("NomeProduto", new Rule <Produto>(NomeProduto, "O campo Nome deve ser preenhcido.")); Add("CategoriaProduto", new Rule <Produto>(CategoriaProduto, "Selecione a categoria do produto.")); }
public void ShouldAcceptMultipleExpressions() { var spec1 = new GenericSpecification<User>(user => user.FavoriteNumber == 2); var spec2 = new GenericSpecification<User>(user => !user.IsMale); var spec3 = new GenericSpecification<User>(user => user.Name == "Maria Lucia"); var result = new UserRepository().Single(spec1 & spec2 & spec3); Assert.Equal("Maria Lucia", result.Name); }
public void ShouldVerifySpecificItem() { var spec = new GenericSpecification<User>(u => u.FavoriteNumber > 3); var user1 = new User { FavoriteNumber = 4 }; Assert.True(spec.IsSatisfiedBy(user1)); var user2 = new User { FavoriteNumber = 1 }; Assert.False(spec.IsSatisfiedBy(user2)); }
public void ShouldMergeExpressions() { var spec1 = new GenericSpecification<User>(user => user.FavoriteNumber == 2); var spec2 = new GenericSpecification<User>(user => user.FavoriteNumber == 3); var result = this.Context.Users.Where(spec1 | spec2).ToList(); Assert.Collection(result, user => Assert.Equal("Maria Lucia", user.Name), user => Assert.Equal("Johny Pericles", user.Name)); }
public void OrPlusNegate() { var spec1 = new GenericSpecification<User>(user => !user.IsMale); var spec2 = new GenericSpecification<User>(user => user.Name == "John Lister"); var result = new UserRepository().Where(!(spec1 | spec2)).ToList(); Assert.Collection(result, user => Assert.Equal("Jorge Mario", user.Name), user => Assert.Equal("Johny Pericles", user.Name)); }
public IEnumerable <M> GetRelated(O o) { Func <ManyToManyElement <M, O>, bool> validator = (ManyToManyElement <M, O> element) => element.GetOId == o.id; var spec = new GenericSpecification <ManyToManyElement <M, O> >(validator); var relatedIds = _repo.GetBySpecification(spec).GroupBy(x => x.GetMId).Select(grp => grp.First().GetMId); Func <M, bool> relatedValidator = (M m) => relatedIds.Contains(m.id); var relatedSpec = new GenericSpecification <M>(relatedValidator); return(InMemoryRepository <M> .GetInstance().GetBySpecification(relatedSpec)); }
public void ShouldMergeExpressions() { var isMaleSpec = new GenericSpecification<User>(user => user.IsMale); var favoriteNumberSpec = new GenericSpecification<User>(user => user.FavoriteNumber == 1); var result = new UserRepository().Where(isMaleSpec & favoriteNumberSpec).ToList(); Assert.Collection(result, user => Assert.Equal("Jorge Mario", user.Name), user => Assert.Equal("John Lister", user.Name)); }
public void Not_CreatesNotSpecification() { // Arrange var spec = new GenericSpecification(false); // Act var actualSpec = spec.Not(); // Assert Assert.That(actualSpec, Is.TypeOf <NotSpecification <TestingInfrastructure.DomainModeling.TestModels.TestAggregateRoot, long> >()); }
public void Specification_GenericSpecification_ShouldReturnTrue() { // Arrange var movie = MovieFactory.GetMixedMovies().FirstOrDefault(m => m.MpaaRating > MpaaRating.PG && m.Rating >= 4); var genSpec = new GenericSpecification <Movie>(m => m.MpaaRating > MpaaRating.PG && m.Rating >= 4); // Act var result = genSpec.IsSatisfiedBy(movie); // Assert Assert.True(result); }
public void AndPlusNegate() { var spec1 = new GenericSpecification<User>(user => user.IsMale); var spec2 = new GenericSpecification<User>(user => user.FavoriteNumber == 3); var result = new UserRepository().Where(!(spec1 & spec2)).ToList(); Assert.Collection(result, user => Assert.Equal("Jorge Mario", user.Name), user => Assert.Equal("Maria Lucia", user.Name), user => Assert.Equal("John Lister", user.Name)); }
public void Or_CreatesOrSpecification() { // Arrange var spec = new GenericSpecification(false); var anotherSpec = new GenericSpecification(true); // Act var actualSpec = spec.Or(anotherSpec); // Assert Assert.That(actualSpec, Is.TypeOf <OrSpecification <TestingInfrastructure.DomainModeling.TestModels.TestAggregateRoot, long> >()); }
public void True_Equals_False() { // Arrange var trueSpec = new GenericSpecification(true); var notSpec = new NotSpecification <TestAggregateRoot, long>(trueSpec); // Act var actualSpecResult = notSpec.IsSatisfiedBy(null); // Assert Assert.IsFalse(actualSpecResult); }
public void Or_specification_is_satisfied_when_either_of_expression_is_true_for_candidate_obect() { var candidateObject = new TestClass() { DepartmentName = "Sales", Salary = 3000 }; var salarySpecification = new GenericSpecification<TestClass>(t => t.Salary > 4000); var departmentSpecification = new GenericSpecification<TestClass>(t => t.DepartmentName == "Sales"); var orSpecification = salarySpecification.Or(departmentSpecification); var isSatisfied = orSpecification.IsSatisfiedBy(candidateObject); Assert.IsTrue(isSatisfied); }
public void LeftFalse_RightFalse_EqualsFalse() { // Arrange var falseSpec = new GenericSpecification(false); var andSpec = new AndSpecification <TestAggregateRoot, long>(falseSpec, falseSpec); // Act var actualSpecResult = andSpec.IsSatisfiedBy(null); // Assert Assert.IsFalse(actualSpecResult); }
public void LeftFalse_RightFalse_EqualsFalse() { // Arrange var falseSpec = new GenericSpecification(false); var orSpec = new OrSpecification <TestAggregateRoot, long>(falseSpec, falseSpec); // Act var actualSpecResult = orSpec.ToExpression().Compile()(null); // Assert Assert.IsFalse(actualSpecResult); }
public void LeftTrue_RightTrue_EqualsTrue() { // Arrange var trueSpec = new GenericSpecification(true); var orSpec = new OrSpecification <TestAggregateRoot, long>(trueSpec, trueSpec); // Act var actualSpecResult = orSpec.IsSatisfiedBy(null); // Assert Assert.IsTrue(actualSpecResult); }
public void And_specification_is_satisfied_when_both_expressions_are_true_for_candidate_obect() { var candidateObject = new TestClass() { DepartmentName = "Sales", Salary = 5000 }; var salarySpecification = new GenericSpecification<TestClass>(t => t.Salary > 4000); var departmentSpecification = new GenericSpecification<TestClass>(t=>t.DepartmentName=="Sales"); var andSpecification = salarySpecification.And(departmentSpecification); var isSatisfied = andSpecification.IsSatisfiedBy(candidateObject); Assert.IsTrue(isSatisfied); }
public static string Swap(this GenericSpecification spec, string str) { if (spec == null) { return(str); } if (spec.Specifications.TryGetValue(str, out var swap)) { return(swap); } return(str); }
public ClienteEstaConsistenteValidation() { var CPFCliente = new ClienteDeveTerCpfValidoSpecification(); var clienteEmail = new ClienteDeveTerEmailValidoSpecification(); var clienteMaioridade = new ClienteDeveSerMaiorDeIdadeSpecification(); var clienteNomeCurto = new GenericSpecification <Cliente>(c => c.Nome.Length >= 2); // Tem que ter //Pode colocar a mensagem de erro em um arquivo Resource Add("CPFCliente", new Rule <Cliente>(CPFCliente, "Cliente informou um CPF inválido.")); Add("clienteEmail", new Rule <Cliente>(clienteEmail, "Cliente informou um e-amil inválido.")); Add("clienteMaioridade", new Rule <Cliente>(clienteMaioridade, "Cliente não tem maioridade para cadastro.")); Add("clienteNomeCurto", new Rule <Cliente>(clienteNomeCurto, "Nome do cliente precisa ter mais de 2 caracteres.")); }
public void Specification_filters_out_non_matching_objects_from_ienumerable() { var testObjects = new List<TestClass>(); testObjects.Add(new TestClass() { Salary = 3000 }); testObjects.Add(new TestClass() { Salary = 5000 }); testObjects.Add(new TestClass() { Salary = 6000 }); var specification = new GenericSpecification<TestClass>(t => t.Salary > 4000); var filteredQuery = specification.Filter(testObjects); AsserThatAllTestObjectHasSalaryGreaterThan(filteredQuery, 4000); }
public void AllOperators() { var spec1 = new GenericSpecification<User>(user => user.FavoriteNumber == 1); var spec2 = new GenericSpecification<User>(user => user.Name == "John Lister"); var spec3 = new GenericSpecification<User>(user => user.IsMale); var result = new UserRepository().Where(!((spec1 & spec2) | !spec3)).ToList(); Assert.Collection(result, user => Assert.Equal("Jorge Mario", user.Name), user => Assert.Equal("Johny Pericles", user.Name)); }
public void ShouldAcceptMultipleExpressions() { var spec1 = new GenericSpecification<User>(user => user.Name == "Maria Lucia"); var spec2 = new GenericSpecification<User>(user => user.Name == "John Lister"); var spec3 = new GenericSpecification<User>(user => user.Name == "Johny Pericles"); var result = this.Context.Users.Where(spec1 | spec2 | spec3).ToList(); Assert.Collection(result, user => Assert.Equal("Maria Lucia", user.Name), user => Assert.Equal("John Lister", user.Name), user => Assert.Equal("Johny Pericles", user.Name)); }
public void AndPlusOr() { var spec1 = new GenericSpecification<User>(user => user.IsMale); var spec2 = new GenericSpecification<User>(user => user.FavoriteNumber == 3); var spec3 = new GenericSpecification<User>(user => !user.IsMale); var spec4 = new GenericSpecification<User>(user => user.FavoriteNumber == 2); var result = new UserRepository().Where((spec1 & spec2) | (spec3 & spec4)).ToList(); Assert.Collection(result, user => Assert.Equal("Maria Lucia", user.Name), user => Assert.Equal("Johny Pericles", user.Name)); }
public IReadOnlyList <Movie> Find(GenericSpecification <Movie> specification) { Data = new List <Movie>() { new Movie("Avatar", 2012), new Movie("Terminator", 1987), new Movie("Toy Story", 2000), }.AsQueryable(); return(Data .Where(specification.Expression) .ToList()); }
public ClienteEstaConsistenteValidation() { //var CPFCliente = new ClienteDeveTerCpfValidoSpecification(); var clienteEmail = new ClienteDeveTerEmailValidoSpecification(); var clienteMaioridade = new ClienteDeveSerMaiorDeIdadeSpecification(); var clienteNomeCurto = new GenericSpecification <Cliente>(c => c.Nome.Length >= 2); var clienteEmailVazio = new GenericSpecification <Cliente>(c => !string.IsNullOrWhiteSpace(c.Email)); var CPFCliente = new GenericSpecification <Cliente>(c => CPF.Validar(c.CPF)); Add("CPFCliente", new Rule <Cliente>(CPFCliente, "Cliente informou um CPF inválido.")); Add("clienteEmail", new Rule <Cliente>(clienteEmail, "Cliente informou um e-mail inválido.")); Add("clienteMaioridade", new Rule <Cliente>(clienteMaioridade, "Cliente não tem maioridade para cadastro.")); Add("clienteNomeCurto", new Rule <Cliente>(clienteNomeCurto, "O nome do cliente precisa ter mais de 2 caracteres.")); Add("clienteEmailVazio", new Rule <Cliente>(clienteEmailVazio, "O e-mail não pode estar em branco.")); }
//https://enterprisecraftsmanship.com/posts/specification-pattern-c-implementation/ static void Main(string[] args) { var genericRepository = new GenericRepository(); var specification1 = new GenericSpecification <Movie>(x => x.Year > 2000); var movies1 = genericRepository.Find(specification1); var repository = new MovieRepository(); var specification2 = new YearSpecification(2000); var movies2 = repository.Find(specification2); var specification3 = new YearAndTitleSpecification(2000, "inator"); var movies3 = repository.Find(specification3); }
public void AddExpressionToSpecificationtoBeSatisified(long propertyValue, long specificationValue, bool expectedResult) { //Arrange var aTestClassWithValue = new TestClass() { SomeProperyValue = propertyValue }; IGenericSpecification <TestClass> specification = new GenericSpecification <TestClass>(x => x.SomeProperyValue <= specificationValue); //Action var actualresult = specification.IsSatisfiedBy(aTestClassWithValue); //Assert Assert.True(specification is IGenericSpecification <TestClass>); Assert.Equal(expectedResult, actualresult); }
public ClienteEstaConsistenteValidation() { //var CPFCliente = new ClienteDeveTerCpfValidoSpecification(); var clienteEmail = new ClienteDeveTerEmailValidoSpecification(); var clienteMaiorIdade = new ClienteDeveSerMaiorDeIdadeSpecification(); // Aqui temos exemplos usando uma classe bem genérica, detalhes em GenericSpecification var clienteNomeCurto = new GenericSpecification <Cliente>(c => c.Nome.Length >= 2); var clienteEmailVazio = new GenericSpecification <Cliente>(c => !string.IsNullOrEmpty(c.Email)); var CPFCliente = new GenericSpecification <Cliente>(c => CPF.Validar(c.CPF)); Add("CPFCliente", new Rule <Cliente>(CPFCliente, "Cliente informou um CPF inválido")); Add("clienteEmail", new Rule <Cliente>(clienteEmail, "Cliente informou um E-mail inválido")); Add("clienteMaiorIdade", new Rule <Cliente>(clienteMaiorIdade, "Cliente precisa ser maior de idade")); Add("clienteNomeCurto", new Rule <Cliente>(clienteNomeCurto, "O nome do cliente precisa ter mais de 2 caracteres")); Add("clienteEmailVazio", new Rule <Cliente>(clienteEmailVazio, "O e-mail do cliente não pode estar em branco")); }
public string BuyChildTicket(int movieId) { var movie = repository.GetById(movieId); if (movie == null) { return("Movie doesn't exist"); } var specification = new GenericSpecification <MovieMiddle>(MovieMiddle.IsSuitableForChildren); if (!specification.IsSatisfiedBy(movie)) { return("This movie is not available for children"); } return("Children ticket were bought successfully"); }
public string BuyAvailableOnCdTicket(int movieId) { var movie = repository.GetById(movieId); if (movie == null) { return("Movie doesn't exist"); } var specification = new GenericSpecification <MovieMiddle>(MovieMiddle.HasCdVersion); if (!specification.IsSatisfiedBy(movie)) { return("This movie doesn't have CD version"); } return("Children ticket were bought successfully"); }
public async Task <IEnumerable <TEntity> > FindAllAsync(ISpecification <TEntity> specification) { GenericSpecification <TEntity> genericSpecification = specification as GenericSpecification <TEntity>; FeedIterator <TEntity> iterator = null; if (genericSpecification.OrderBy == null) { iterator = this._container.GetItemLinqQueryable <TEntity>().Where(specification.Predicate).ToFeedIterator(); } else { if (genericSpecification.Order == Order.Asc) { iterator = this._container.GetItemLinqQueryable <TEntity>().Where(specification.Predicate).OrderBy(specification.OrderBy).ToFeedIterator(); } else { iterator = this._container.GetItemLinqQueryable <TEntity>().Where(specification.Predicate).OrderByDescending(specification.OrderBy).ToFeedIterator(); } } List <TEntity> results = new List <TEntity>(); while (iterator.HasMoreResults) { var response = await iterator.ReadNextAsync(); foreach (var item in response) { results.Add(item); } } return(results); }
public CategoriaConsistenteValidation() { var NomeCategoria = new GenericSpecification <Categoria>(c => !string.IsNullOrWhiteSpace(c.Nome)); Add("NomeCategoria", new Rule <Categoria>(NomeCategoria, "O campo Nome deve ser preenhcido.")); }
public void Specification_is_satisfied_when_expression_is_true_for_candidate_object() { var candidateObject = new TestClass() {Salary = 5000}; var specification = new GenericSpecification<TestClass>(t=>t.Salary>4000); var isSatisfied = specification.IsSatisfiedBy(candidateObject); Assert.IsTrue(isSatisfied); }
public static async IAsyncEnumerable <ObjectGeneration> IterateMajorRecords(ObjectGeneration obj, bool includeBaseClass, bool includeSelf, GenericSpecification specifications = null) { foreach (var field in obj.IterateFields(includeBaseClass: includeBaseClass)) { if (field is LoquiType loqui) { if (includeSelf && loqui.TargetObjectGeneration != null && await loqui.TargetObjectGeneration.IsMajorRecord()) { yield return(loqui.TargetObjectGeneration); } await foreach (var item in IterateMajorRecords(loqui, includeBaseClass, specifications)) { yield return(item); } } else if (field is ContainerType cont) { if (cont.SubTypeGeneration is LoquiType contLoqui) { await foreach (var item in IterateMajorRecords(contLoqui, includeBaseClass, specifications)) { yield return(item); } } } else if (field is DictType dict) { if (dict.ValueTypeGen is LoquiType valLoqui) { await foreach (var item in IterateMajorRecords(valLoqui, includeBaseClass, specifications)) { yield return(item); } } if (dict.KeyTypeGen is LoquiType keyLoqui) { await foreach (var item in IterateMajorRecords(keyLoqui, includeBaseClass, specifications)) { yield return(item); } } } } }
public static async IAsyncEnumerable <ObjectGeneration> IterateMajorRecords(LoquiType loqui, bool includeBaseClass, GenericSpecification specifications = null) { if (specifications?.Specifications.Count > 0) { foreach (var target in specifications.Specifications.Values) { if (!ObjectNamedKey.TryFactory(target, out var key)) { continue; } var specObj = loqui.ObjectGen.ProtoGen.Gen.ObjectGenerationsByObjectNameKey[key]; if (await specObj.IsMajorRecord()) { yield return(specObj); } await foreach (var item in IterateMajorRecords(specObj, includeBaseClass, includeSelf: true, loqui.GenericSpecification)) { yield return(item); } } } else if (loqui.TargetObjectGeneration != null) { if (await loqui.TargetObjectGeneration.IsMajorRecord()) { yield return(loqui.TargetObjectGeneration); } await foreach (var item in IterateMajorRecords(loqui.TargetObjectGeneration, includeBaseClass, includeSelf: true, loqui.GenericSpecification)) { yield return(item); } } else if (loqui.RefType == LoquiType.LoquiRefType.Interface) { // Must be a link interface if (!LinkInterfaceModule.ObjectMappings[loqui.ObjectGen.ProtoGen.Protocol].TryGetValue(loqui.SetterInterface, out var mappings)) { throw new ArgumentException(); } foreach (var obj in mappings) { yield return(obj); } } else { throw new ArgumentException(); } }
public static async Task <Case> HasMajorRecords(ObjectGeneration obj, bool includeBaseClass, bool includeSelf, GenericSpecification specifications = null) { if (obj.Name == "ListGroup") { return(Case.Yes); } foreach (var field in obj.IterateFields(includeBaseClass: includeBaseClass)) { if (field is LoquiType loqui) { if (includeSelf && loqui.TargetObjectGeneration != null && await loqui.TargetObjectGeneration.IsMajorRecord()) { return(Case.Yes); } if (await HasMajorRecords(loqui, includeBaseClass, specifications) == Case.Yes) { return(Case.Yes); } } else if (field is ContainerType cont) { if (cont.SubTypeGeneration is LoquiType contLoqui) { if (await HasMajorRecords(contLoqui, includeBaseClass, specifications) == Case.Yes) { return(Case.Yes); } } } else if (field is DictType dict) { if (dict.ValueTypeGen is LoquiType valLoqui) { if (await HasMajorRecords(valLoqui, includeBaseClass, specifications) == Case.Yes) { return(Case.Yes); } } if (dict.KeyTypeGen is LoquiType keyLoqui) { if (await HasMajorRecords(keyLoqui, includeBaseClass, specifications) == Case.Yes) { return(Case.Yes); } } } } return(Case.No); }
public static async Task <Case> HasMajorRecords(LoquiType loqui, bool includeBaseClass, GenericSpecification specifications = null, bool includeSelf = true) { if (loqui.TargetObjectGeneration != null) { if (includeSelf && await loqui.TargetObjectGeneration.IsMajorRecord()) { return(Case.Yes); } return(await MajorRecordModule.HasMajorRecordsInTree(loqui.TargetObjectGeneration, includeBaseClass, loqui.GenericSpecification)); } else if (specifications != null) { foreach (var target in specifications.Specifications.Values) { if (!ObjectNamedKey.TryFactory(target, out var key)) { continue; } var specObj = loqui.ObjectGen.ProtoGen.Gen.ObjectGenerationsByObjectNameKey[key]; if (await specObj.IsMajorRecord()) { return(Case.Yes); } return(await MajorRecordModule.HasMajorRecordsInTree(specObj, includeBaseClass)); } } else if (loqui.RefType == LoquiType.LoquiRefType.Interface) { // ToDo // Quick hack. Real solution should use reflection to investigate the interface return(includeSelf ? Case.Yes : Case.No); } return(Case.Maybe); }
public static async Task <Case> HasMajorRecordsInTree(ObjectGeneration obj, bool includeBaseClass, GenericSpecification specifications = null) { if (await HasMajorRecords(obj, includeBaseClass: includeBaseClass, includeSelf: false, specifications: specifications) == Case.Yes) { return(Case.Yes); } // If no, check subclasses foreach (var inheritingObject in await obj.InheritingObjects()) { if (await HasMajorRecordsInTree(inheritingObject, includeBaseClass: false, specifications: specifications) == Case.Yes) { return(Case.Yes); } } return(Case.No); }
public static async Task <Case> HasLinks(LoquiType loqui, bool includeBaseClass, GenericSpecification specifications = null) { if (loqui.TargetObjectGeneration != null) { return(await HasLinks(loqui.TargetObjectGeneration, includeBaseClass, loqui.GenericSpecification)); } else if (specifications != null) { foreach (var target in specifications.Specifications.Values) { if (!ObjectNamedKey.TryFactory(target, out var key)) { continue; } var specObj = loqui.ObjectGen.ProtoGen.Gen.ObjectGenerationsByObjectNameKey[key]; return(await HasLinks(specObj, includeBaseClass)); } return(Case.Maybe); } else { return(Case.Maybe); } }
public static async Task <Case> HasLinks(ObjectGeneration obj, bool includeBaseClass, GenericSpecification specifications = null) { if (obj.Name == "MajorRecord") { return(Case.Yes); } if (obj.IterateFields(includeBaseClass: includeBaseClass).Any((f) => f is FormLinkType)) { return(Case.Yes); } Case bestCase = Case.No; foreach (var field in obj.IterateFields(includeBaseClass: includeBaseClass)) { if (field is LoquiType loqui) { var subCase = await HasLinks(loqui, includeBaseClass, specifications); if (subCase > bestCase) { bestCase = subCase; } } else if (field is ContainerType cont) { if (cont.SubTypeGeneration is LoquiType contLoqui) { var subCase = await HasLinks(contLoqui, includeBaseClass, specifications); if (subCase > bestCase) { bestCase = subCase; } } else if (cont.SubTypeGeneration is FormLinkType) { return(Case.Yes); } } else if (field is DictType dict) { if (dict.ValueTypeGen is LoquiType valLoqui) { var subCase = await HasLinks(valLoqui, includeBaseClass, specifications); if (subCase > bestCase) { bestCase = subCase; } } if (dict.KeyTypeGen is LoquiType keyLoqui) { var subCase = await HasLinks(keyLoqui, includeBaseClass, specifications); if (subCase > bestCase) { bestCase = subCase; } } if (dict.ValueTypeGen is FormLinkType) { return(Case.Yes); } } } // If no, check subclasses if (bestCase == Case.No) { foreach (var inheritingObject in await obj.InheritingObjects()) { var subCase = await HasLinks(inheritingObject, includeBaseClass : false, specifications : specifications); if (subCase != Case.No) { return(Case.Maybe); } } } return(bestCase); }
protected abstract ISpecification GetSpecification(GenericSpecification <TType> helper);