Skip to content

Instantly share code, notes, and snippets.

@maurei
Created November 6, 2019 08:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maurei/cfd7e228c0dcb827b159621b4f264a9a to your computer and use it in GitHub Desktop.
Save maurei/cfd7e228c0dcb827b159621b4f264a9a to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using JsonApiDotNetCore.Internal;
using JsonApiDotNetCore.Models;
using Microsoft.Extensions.DependencyInjection;
namespace JsonApiDotNetCore.Hooks
{
/// <summary>
/// The default implementation for IHooksDiscovery
/// </summary>
public class HooksDiscovery<TEntity> : IHooksDiscovery<TEntity> where TEntity : class, IIdentifiable
{
private readonly ResourceHook[] _allHooks;
private readonly ResourceHook[] _databaseValuesAttributeAllowed =
{
ResourceHook.BeforeUpdate,
ResourceHook.BeforeUpdateRelationship,
ResourceHook.BeforeDelete
};
/// <inheritdoc/>
public ResourceHook[] ImplementedHooks { get; private set; }
public ResourceHook[] DatabaseValuesEnabledHooks { get; private set; }
public ResourceHook[] DatabaseValuesDisabledHooks { get; private set; }
public HooksDiscovery(IServiceProvider provider)
{
_allHooks = Enum.GetValues(typeof(ResourceHook))
.Cast<ResourceHook>()
.Where(h => h != ResourceHook.None)
.ToArray();
using (var scope = provider.CreateScope())
{
var container = scope.ServiceProvider.GetService(typeof(ResourceDefinition<TEntity>));
if (container == null)
return;
DiscoverImplementedHooksForModel(container.GetType());
}
}
/// <summary>
/// Discovers the implemented hooks for a model.
/// </summary>
/// <returns>The implemented hooks for model.</returns>
void DiscoverImplementedHooksForModel(Type containerType)
{
var implementedHooks = new List<ResourceHook>();
var enabledHooks = new List<ResourceHook>() { ResourceHook.BeforeImplicitUpdateRelationship } ;
var disabledHooks = new List<ResourceHook>();
if (containerType != null)
{
foreach (var hook in _allHooks)
{
var method = containerType.GetMethod(hook.ToString("G"));
implementedHooks.Add(hook);
var attr = method.GetCustomAttributes(true).OfType<LoadDatabaseValues>().SingleOrDefault();
if (attr != null)
{
if (!_databaseValuesAttributeAllowed.Contains(hook))
{
throw new JsonApiSetupException($"DatabaseValuesAttribute cannot be used on hook" +
$"{hook.ToString("G")} in resource definition {containerType.Name}");
}
var targetList = attr.value ? enabledHooks : disabledHooks;
targetList.Add(hook);
}
}
}
ImplementedHooks = implementedHooks.ToArray();
DatabaseValuesDisabledHooks = disabledHooks.ToArray();
DatabaseValuesEnabledHooks = enabledHooks.ToArray();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment