/// <summary> /// For a given <see cref="ResourceHook" /> target and for a given type <typeparamref name="TResource" />, gets the hook container if the target hook was /// implemented and should be executed. /// <para /> /// Along the way, creates a traversable node from the root resource set. /// </summary> /// <returns> /// <c>true</c>, if hook was implemented, <c>false</c> otherwise. /// </returns> private GetHookResult <TResource> GetHook <TResource>(ResourceHook target, IEnumerable <TResource> resources) where TResource : class, IIdentifiable { RootNode <TResource> node = _nodeNavigator.CreateRootNode(resources); IResourceHookContainer <TResource> container = _containerProvider.GetResourceHookContainer <TResource>(target); return(new GetHookResult <TResource>(container, node)); }
/// <summary> /// For a given <see cref="ResourceHook"/> target and for a given type /// <typeparamref name="TResource"/>, gets the hook container if the target /// hook was implemented and should be executed. /// <para /> /// Along the way, creates a traversable node from the root resource set. /// </summary> /// <returns><c>true</c>, if hook was implemented, <c>false</c> otherwise.</returns> private bool GetHook <TResource>(ResourceHook target, IEnumerable <TResource> resources, out IResourceHookContainer <TResource> container, out RootNode <TResource> node) where TResource : class, IIdentifiable { node = _traversalHelper.CreateRootNode(resources); container = _executorHelper.GetResourceHookContainer <TResource>(target); return(container != null); }
/// <summary> /// A helper method to call a hook on <paramref name="container"/> reflectively. /// </summary> private IEnumerable CallHook(IResourceHookContainer container, ResourceHook hook, object[] arguments) { var method = container.GetType().GetMethod(hook.ToString("G")); // note that some of the hooks return "void". When these hooks, the // are called reflectively with Invoke like here, the return value // is just null, so we don't have to worry about casting issues here. return((IEnumerable)ThrowJsonApiExceptionOnError(() => method.Invoke(container, arguments))); }
/// <summary> /// given the set of <paramref name="uniqueEntities"/>, it will load all the /// values from the database of these entites. /// </summary> /// <returns>The db values.</returns> /// <param name="entityType">type of the entities to be loaded</param> /// <param name="uniqueEntities">The set of entities to load the db values for</param> /// <param name="targetHook">The hook in which the db values will be displayed.</param> /// <param name="relationshipsToNextLayer">Relationships from <paramref name="entityType"/> to the next layer: /// this indicates which relationships will be included on <paramref name="uniqueEntities"/>.</param> IEnumerable LoadDbValues(Type entityType, IEnumerable uniqueEntities, ResourceHook targetHook, RelationshipAttribute[] relationshipsToNextLayer) { /// We only need to load database values if the target hook of this hook execution /// cycle is compatible with displaying database values and has this option enabled. if (!_executorHelper.ShouldLoadDbValues(entityType, targetHook)) { return(null); } return(_executorHelper.LoadDbValues(entityType, uniqueEntities, targetHook, relationshipsToNextLayer)); }
public bool ShouldLoadDbValues(Type entityType, ResourceHook hook) { var discovery = GetHookDiscovery(entityType); if (discovery.DatabaseValuesDisabledHooks.Contains(hook)) { return(false); } if (discovery.DatabaseValuesEnabledHooks.Contains(hook)) { return(true); } return(_options.LoadDatabaseValues); }
/// <summary> /// Traverses the nodes in a <see cref="NodeLayer"/>. /// </summary> private void Traverse(NodeLayer currentLayer, ResourceHook target, Action <IResourceHookContainer, IResourceNode> action) { var nextLayer = currentLayer; while (true) { if (!nextLayer.AnyResources()) { return; } TraverseNextLayer(nextLayer, action, target); nextLayer = _traversalHelper.CreateNextLayer(nextLayer.ToList()); } }
private void TraverseNodesInLayer(IEnumerable <IResourceNode> currentLayer, ResourceHook target, Action <IResourceHookContainer, IResourceNode> action) { IEnumerable <IResourceNode> nextLayer = currentLayer; while (true) { if (!HasResources(nextLayer)) { return; } TraverseNextLayer(nextLayer, action, target); nextLayer = _nodeNavigator.CreateNextLayer(nextLayer.ToList()); } }
/// <summary> /// Traverses the nodes in a <see cref="NodeLayer"/>. /// </summary> private void Traverse(NodeLayer currentLayer, ResourceHook target, Action <IResourceHookContainer, IResourceNode> action) { if (!currentLayer.AnyResources()) { return; } foreach (IResourceNode node in currentLayer) { var resourceType = node.ResourceType; var hookContainer = _executorHelper.GetResourceHookContainer(resourceType, target); if (hookContainer == null) { continue; } action(hookContainer, node); } Traverse(_traversalHelper.CreateNextLayer(currentLayer.ToList()), target, action); }
/// <inheritdoc/> public IResourceHookContainer GetResourceHookContainer(RightType rightType, ResourceHook hook = ResourceHook.None) { // checking the cache if we have a reference for the requested container, // regardless of the hook we will use it for. If the value is null, // it means there was no implementation IResourceHookContainer at all, // so we need not even bother. if (!_hookContainers.TryGetValue(rightType, out IResourceHookContainer container)) { container = (_genericProcessorFactory.Get <IResourceHookContainer>(typeof(ResourceDefinition <>), rightType)); _hookContainers[rightType] = container; } if (container == null) { return(container); } // if there was a container, first check if it implements the hook we // want to use it for. List <ResourceHook> targetHooks; if (hook == ResourceHook.None) { CheckForTargetHookExistence(); targetHooks = _targetedHooksForRelatedEntities; } else { targetHooks = new List <ResourceHook>() { hook }; } foreach (ResourceHook targetHook in targetHooks) { if (ShouldExecuteHook(rightType, targetHook)) { return(container); } } return(null); }
public void AddHook <T>(IResourceable <T> resourceable, ResourceHook <T> hook) where T : IKeyed, INameable { if (resourceable.IsFrozen) { var e = resourceable.GetResourceables(); foreach (var item in e) { hook(item); } } ResourceHook <T> hooks; if (_resourceHooks.TryGetValue(resourceable, out var hooksObj)) { hooks = (ResourceHook <T>)hooksObj; hooks += hook; } else { hooks = hook; } _resourceHooks[resourceable] = hooks; }
/// <summary> /// given the set of <paramref name="uniqueResources" />, it will load all the values from the database of these resources. /// </summary> /// <returns> /// The db values. /// </returns> /// <param name="resourceType"> /// type of the resources to be loaded /// </param> /// <param name="uniqueResources"> /// The set of resources to load the db values for /// </param> /// <param name="targetHook"> /// The hook in which the db values will be displayed. /// </param> /// <param name="relationshipsToNextLayer"> /// Relationships from <paramref name="resourceType" /> to the next layer: this indicates which relationships will be included on /// <paramref name="uniqueResources" />. /// </param> private IEnumerable LoadDbValues(Type resourceType, IEnumerable uniqueResources, ResourceHook targetHook, RelationshipAttribute[] relationshipsToNextLayer) { // We only need to load database values if the target hook of this hook execution // cycle is compatible with displaying database values and has this option enabled. if (!_containerProvider.ShouldLoadDbValues(resourceType, targetHook)) { return(null); } return(_containerProvider.LoadDbValues(resourceType, uniqueResources, relationshipsToNextLayer)); }
public IEnumerable LoadDbValues(LeftType entityTypeForRepository, IEnumerable entities, ResourceHook hook, params RelationshipAttribute[] relationshipsToNextLayer) { var idType = TypeHelper.GetIdType(entityTypeForRepository); var parameterizedGetWhere = GetType() .GetMethod(nameof(GetWhereAndInclude), BindingFlags.NonPublic | BindingFlags.Instance) .MakeGenericMethod(entityTypeForRepository, idType); var cast = ((IEnumerable <object>)entities).Cast <IIdentifiable>(); var ids = cast.Select(TypeHelper.GetResourceTypedId).CopyToList(idType); var values = (IEnumerable)parameterizedGetWhere.Invoke(this, new object[] { ids, relationshipsToNextLayer }); if (values == null) { return(null); } return((IEnumerable)Activator.CreateInstance(typeof(HashSet <>).MakeGenericType(entityTypeForRepository), values.CopyToList(entityTypeForRepository))); }
/// <inheritdoc/> public IResourceHookContainer <TResource> GetResourceHookContainer <TResource>(ResourceHook hook = ResourceHook.None) where TResource : class, IIdentifiable { return((IResourceHookContainer <TResource>)GetResourceHookContainer(typeof(TResource), hook)); }
private bool ShouldExecuteHook(RightType entityType, ResourceHook hook) { var discovery = GetHookDiscovery(entityType); return(discovery.ImplementedHooks.Contains(hook)); }
private bool ShouldExecuteHook(RightType resourceType, ResourceHook hook) { IHooksDiscovery discovery = GetHookDiscovery(resourceType); return(discovery.ImplementedHooks.Contains(hook)); }
public HashSet <TResource> LoadDbValues <TResource>(IEnumerable <TResource> entities, ResourceHook hook, params RelationshipAttribute[] relationships) where TResource : class, IIdentifiable { var entityType = typeof(TResource); var dbValues = LoadDbValues(entityType, entities, hook, relationships)?.Cast <TResource>(); if (dbValues == null) { return(null); } return(new HashSet <TResource>(dbValues)); }
private void TraverseNextLayer(NodeLayer nextLayer, Action <IResourceHookContainer, IResourceNode> action, ResourceHook target) { foreach (IResourceNode node in nextLayer) { var hookContainer = _executorHelper.GetResourceHookContainer(node.ResourceType, target); if (hookContainer != null) { action(hookContainer, node); } } }
private void TraverseNextLayer(IEnumerable <IResourceNode> nextLayer, Action <IResourceHookContainer, IResourceNode> action, ResourceHook target) { foreach (IResourceNode node in nextLayer) { IResourceHookContainer hookContainer = _containerProvider.GetResourceHookContainer(node.ResourceType, target); if (hookContainer != null) { action(hookContainer, node); } } }
/// <inheritdoc/> public IResourceHookContainer <TEntity> GetResourceHookContainer <TEntity>(ResourceHook hook = ResourceHook.None) where TEntity : class, IIdentifiable { return((IResourceHookContainer <TEntity>)GetResourceHookContainer(typeof(TEntity), hook)); }
public IEnumerable LoadDbValues(PrincipalType entityTypeForRepository, IEnumerable entities, ResourceHook hook, params RelationshipAttribute[] relationships) { var paths = relationships.Select(p => p.RelationshipPath).ToArray(); var idType = GetIdentifierType(entityTypeForRepository); var parameterizedGetWhere = GetType() .GetMethod(nameof(GetWhereAndInclude), BindingFlags.NonPublic | BindingFlags.Instance) .MakeGenericMethod(entityTypeForRepository, idType); var casted = ((IEnumerable <object>)entities).Cast <IIdentifiable>(); var ids = casted.Select(e => e.StringId).Cast(idType); var values = (IEnumerable)parameterizedGetWhere.Invoke(this, new object[] { ids, paths }); if (values == null) { return(null); } return((IEnumerable)Activator.CreateInstance(typeof(HashSet <>).MakeGenericType(entityTypeForRepository), values.Cast(entityTypeForRepository))); }