示例#1
0
        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();
        }
示例#2
0
        /// <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
                });
            }
        }
示例#3
0
        /// <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);
        }
示例#4
0
        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);
        }
示例#5
0
        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();
        }
示例#6
0
        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);
        }
示例#7
0
        /// <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
                });
            }
        }
示例#8
0
        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();
        }
示例#9
0
        /// <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);
        }