public RelationSavingEngine( IServiceProvider serviceProvider, InformationRessource informationRessource, PropertyInfo propertyRelation, RelationshipJsonApiAttribute relationshipJApiAttribute, object idRessourceParent) { this._serviceProvider = serviceProvider; this._informationRessource = informationRessource; this._relationProperty = propertyRelation; this._idRessourceParent = idRessourceParent; (PropertyInfo foreignKeyProperty, ForeignKeyJsonApiAttribute foreignKeyAttribute) = AttributeRelationsHandling.FindForeignKeyPropertyAndAttribute(this._informationRessource.TypeRessource, this._relationProperty.Name); if (foreignKeyProperty == null && foreignKeyAttribute == null) { throw new JsonApiArchitectureException($"ForeignKeyJsonApi manquant pour {this._relationProperty.Name} dans {this._informationRessource.TypeRessource.Name}, ajouter[ForeignKeyJsonApi (RelationName = nameof({this._relationProperty.Name}))]"); } this._foreignKeyProperty = foreignKeyProperty; this._typeRelation = relationshipJApiAttribute is HasManyJsonApiAttribute ? TypeRelation.Many : TypeRelation.One; this.SaveRelations(); }
/// <summary> /// Parcours les relations et appelle les repository correspondant /// </summary> public void SaveRelation() { if (!this._informationRessource.HaveType) { return; } if (this._informationRessource.IsEnum) { return; } object idRessource = AttributeHandling.GetIdProperty(this._informationRessource.TypeRessource).GetValue(this._informationRessource.Ressource); // Parcours des relations foreach (Tuple <PropertyInfo, RelationshipJsonApiAttribute> relation in AttributeRelationsHandling.GetRelationshipProperties(this._informationRessource.TypeRessource)) { //Instantiation de la classe RelationSavingEngine avec son type de ressource Type typeRessource = relation.Item1.PropertyType.IsGenericType ? relation.Item1.PropertyType.GetGenericArguments()[0] : relation.Item1.PropertyType; Type typeEngine = typeof(RelationSavingEngine <>).MakeGenericType(typeRessource); Activator.CreateInstance(typeEngine, new object[] { this._serviceProvider, this._informationRessource, relation.Item1, relation.Item2, idRessource }); } }
/// <summary> /// Récuperer l'instance de la classe de critéres à utiliser pour le datasource /// </summary> /// <returns></returns> private object GetCriteres() { Type typeCriteres = this._foreignKeyAttribute.Criteres ?? AttributeRelationsHandling.GetCriteresType(typeof(T)); MethodInfo filterMethod = this._queryService.GetType().GetMethod(nameof(IQueryService.FilterOnInclude)).MakeGenericMethod(typeCriteres); object criteres = filterMethod.Invoke(this._queryService, new object[] { AttributeHandling.GetLabelProperty(this._relationProperty) }); if (this._foreignKeyAttribute.Property == null) { if (this._typeRelation == TypeRelation.Many) { (criteres as ICriteresBase).ListeId = this.GetListeIdentifiantMany().ConvertListObjectToListInt(); } else { (criteres as ICriteresBase).ListeId = this.GetListeIdentifiant().ConvertListObjectToListInt(); } (criteres as ICriteresBase).SkipTake = null; } else { typeCriteres.GetProperty(this._foreignKeyAttribute.Property).SetValue(criteres, this.GetListeIdentifiant()); } return(criteres); }
private MethodInfo GetMethodeUpdateInfo(Type repositoryType) { MethodInfo updateMethod = this._typeRelation == TypeRelation.Many ? repositoryType.GetMethod(nameof(JsonApiArchitectureBase.IRepository <T> .UpdateListeAsync)) : repositoryType.GetMethod(nameof(JsonApiArchitectureBase.IRepository <T> .UpdateAsync)); if (updateMethod == null) { throw new JsonApiArchitectureException($"Hériter {AttributeRelationsHandling.GetRepositoryType(typeof(T)).Name} de IRepository"); } return(updateMethod); }
private void UpdateListeWithRepository(MethodInfo updateMethod, object repoInstance, object relationValue) { PropertyInfo foreignKeyProperty = AttributeRelationsHandling.FindForeignKeyPropertyFromType(typeof(T), this._informationRessource.TypeRessource); if (foreignKeyProperty == null) { throw new JsonApiArchitectureException($"Une relation est manquante sur {typeof(T).Name} de type {this._informationRessource.TypeRessource.Name}"); } foreach (object value in (IEnumerable <object>)relationValue) { foreignKeyProperty.SetValue(value, this._idRessourceParent); //new RelationsEngine(this._serviceProvider, this._queryService, value).SaveRelation(); } relationValue = this.CastListToParameterMethod(updateMethod, relationValue); (updateMethod.Invoke(repoInstance, new object[] { relationValue }) as Task).GetAwaiter().GetResult(); }
private object GetRepositoryInstance() { Type repositoryType = AttributeRelationsHandling.GetRepositoryType(typeof(T)); if (repositoryType == null) { throw new JsonApiArchitectureException($"Préciser le repository à utiliser sur {typeof(T).Name} grâce à l'attribute [RessourceJsonApiAttribute]"); } object repoInstance = this._serviceProvider.GetService(repositoryType); if (repoInstance == null) { throw new JsonApiArchitectureException($"Ajouter {repositoryType.Name} dans les services (services.AddScoped<>)"); } return(repoInstance); }
/// <summary> /// Parcours les relations et effectue pour chacune d'elle une requete de récupération. Les résultats trouvés correspondant sont affectés au relations. /// </summary> /// <param name="depth">Niveau de profondeur de relation transmise récursivement</param> public void BuildRelation(int depth = 0, string baseRelationPath = null) { if (depth >= 5) { return; } if (!this._informationRessource.HaveType) { return; } if (baseRelationPath != null) { baseRelationPath += "."; } // Parcours des relations foreach (Tuple <PropertyInfo, RelationshipJsonApiAttribute> relation in AttributeRelationsHandling.GetRelationshipProperties(this._informationRessource.TypeRessource)) { string relationPath = baseRelationPath + AttributeHandling.GetLabelProperty(relation.Item1); if (!this._queryService.IsInclude(relationPath)) { continue; } //Instantiation de la classe RelationsPropertyEngine avec son type de ressource Type typeEngine = typeof(RelationsPropertyEngine <>).MakeGenericType(relation.Item1.GetPropertyTypeSample()); Activator.CreateInstance(typeEngine, new object[] { this._serviceProvider, this._queryService, this._informationRessource, relation.Item1, relation.Item2, relationPath, depth }); } }
public RelationsPropertyEngine( IServiceProvider serviceProvider, IQueryService queryService, InformationRessource informationRessource, PropertyInfo propertyRelation, RelationshipJsonApiAttribute relationshipJApiAttribute, string _relationPath, int depth) { this._serviceProvider = serviceProvider; this._queryService = queryService; this._informationRessource = informationRessource; this._relationProperty = propertyRelation; this._relationAttribute = relationshipJApiAttribute; this._depth = depth; this._relationPath = _relationPath; (PropertyInfo foreignKeyProperty, ForeignKeyJsonApiAttribute foreignKeyAttribute) = AttributeRelationsHandling.FindForeignKeyPropertyAndAttribute(this._informationRessource.TypeRessource, this._relationProperty.Name); if (foreignKeyProperty == null && foreignKeyAttribute == null) { throw new JsonApiArchitectureException($"ForeignKeyJsonApi manquant pour {this._relationProperty.Name} dans {this._informationRessource.TypeRessource.Name}, ajouter[ForeignKeyJsonApi (RelationName = nameof({this._relationProperty.Name}))]"); } this._identifiantRelationProperty = AttributeHandling.GetIdProperty(typeof(T)); if (this._identifiantRelationProperty == null) { throw new JsonApiArchitectureException($"Ajouter [IdJsonApi] sur {typeof(T).Name}"); } this._foreignKeyProperty = foreignKeyProperty; this._foreignKeyAttribute = foreignKeyAttribute; this._typeRelation = this._relationAttribute is HasManyJsonApiAttribute ? TypeRelation.Many : TypeRelation.One; this.GetRelations(); }
/// <summary> /// 1 - Appelle le datasource pour récuperer toutes les relations T /// </summary> private void GetRelations() { // Récupération du datasource définit sur la ressource Type datasourcetype = AttributeRelationsHandling.GetDataSourceType(typeof(T)); if (datasourcetype == null) { throw new JsonApiArchitectureException($"Préciser le datasource à utiliser sur {typeof(T).Name} grâce à l'attribute [RessourceJsonApiAttribute]"); } // Récupération de l'instance du datasource dans les services object datasourceInstance = this._serviceProvider.GetService(datasourcetype); if (datasourceInstance == null) { throw new JsonApiArchitectureException($"Ajouter {datasourcetype.Name} dans les services (services.AddScoped<>)"); } MethodInfo ressourceListeMethod = datasourceInstance.GetType().GetMethod(nameof(JsonApiArchitectureBase.IDataSource <T, ICriteresBase> .GetListeRessourceAsync)) .MakeGenericMethod(new Type[] { typeof(T) }); // Définition des criteres à utiliser pour le datasource object criteres = this.GetCriteres(); // Définition des champs à récuperer List <string> fields = this.GetFields(); // Appelle de la fonction GetListeRessourceAsync<T> et récupération des relations List <T> relations = ((Task <List <T> >)ressourceListeMethod.Invoke(datasourceInstance, new object[] { criteres, fields })).GetAwaiter().GetResult(); // Recherche des relations récursivement new RelationsEngine(this._serviceProvider, this._queryService, relations).BuildRelation(this._depth + 1, this._relationPath); // Affectation des relations trouvées aux bonnes ressources this.BindRelations(relations); }