1
1
using System ;
2
2
using System . Collections . Generic ;
3
3
using System . Linq ;
4
- using JsonApiDotNetCore . Graph ;
5
4
using JsonApiDotNetCore . Internal ;
6
5
using JsonApiDotNetCore . Models ;
6
+ using Microsoft . Extensions . DependencyInjection ;
7
7
8
8
namespace JsonApiDotNetCore . Hooks
9
9
{
@@ -12,78 +12,74 @@ namespace JsonApiDotNetCore.Hooks
12
12
/// </summary>
13
13
public class HooksDiscovery < TResource > : IHooksDiscovery < TResource > where TResource : class , IIdentifiable
14
14
{
15
+ private readonly Type _boundResourceDefinitionType = typeof ( ResourceDefinition < TResource > ) ;
15
16
private readonly ResourceHook [ ] _allHooks ;
16
17
private readonly ResourceHook [ ] _databaseValuesAttributeAllowed =
17
18
{
18
19
ResourceHook . BeforeUpdate ,
19
20
ResourceHook . BeforeUpdateRelationship ,
20
21
ResourceHook . BeforeDelete
21
22
} ;
23
+
22
24
/// <inheritdoc/>
23
25
public ResourceHook [ ] ImplementedHooks { get ; private set ; }
24
26
public ResourceHook [ ] DatabaseValuesEnabledHooks { get ; private set ; }
25
27
public ResourceHook [ ] DatabaseValuesDisabledHooks { get ; private set ; }
26
28
27
-
28
- public HooksDiscovery ( )
29
+ public HooksDiscovery ( IServiceProvider provider )
29
30
{
30
31
_allHooks = Enum . GetValues ( typeof ( ResourceHook ) )
31
32
. Cast < ResourceHook > ( )
32
33
. Where ( h => h != ResourceHook . None )
33
34
. ToArray ( ) ;
34
- DiscoverImplementedHooksForModel ( ) ;
35
+
36
+ Type containerType ;
37
+ using ( var scope = provider . CreateScope ( ) )
38
+ {
39
+ containerType = scope . ServiceProvider . GetService ( _boundResourceDefinitionType ) ? . GetType ( ) ;
40
+ }
41
+
42
+ DiscoverImplementedHooks ( containerType ) ;
35
43
}
36
44
37
45
/// <summary>
38
46
/// Discovers the implemented hooks for a model.
39
47
/// </summary>
40
48
/// <returns>The implemented hooks for model.</returns>
41
- void DiscoverImplementedHooksForModel ( )
49
+ void DiscoverImplementedHooks ( Type containerType )
42
50
{
43
- Type parameterizedResourceDefinition = typeof ( ResourceDefinition < TResource > ) ;
44
- var derivedTypes = TypeLocator . GetDerivedTypes ( typeof ( TResource ) . Assembly , parameterizedResourceDefinition ) . ToList ( ) ;
45
-
46
-
47
- var implementedHooks = new List < ResourceHook > ( ) ;
48
- var enabledHooks = new List < ResourceHook > ( ) { ResourceHook . BeforeImplicitUpdateRelationship } ;
49
- var disabledHooks = new List < ResourceHook > ( ) ;
50
- Type targetType = null ;
51
- try
51
+ if ( containerType == null || containerType == _boundResourceDefinitionType )
52
52
{
53
- targetType = derivedTypes . SingleOrDefault ( ) ; // multiple containers is not supported
53
+ return ;
54
54
}
55
- catch
56
- {
57
- throw new JsonApiSetupException ( $ "It is currently not supported to" +
58
- "implement hooks across multiple implementations of ResourceDefinition<T>" ) ;
59
- }
60
- if ( targetType != null )
55
+
56
+ var implementedHooks = new List < ResourceHook > ( ) ;
57
+ // this hook can only be used with enabled database values
58
+ var databaseValuesEnabledHooks = new List < ResourceHook > { ResourceHook . BeforeImplicitUpdateRelationship } ;
59
+ var databaseValuesDisabledHooks = new List < ResourceHook > ( ) ;
60
+ foreach ( var hook in _allHooks )
61
61
{
62
- foreach ( var hook in _allHooks )
62
+ var method = containerType . GetMethod ( hook . ToString ( "G" ) ) ;
63
+ if ( method . DeclaringType == _boundResourceDefinitionType )
64
+ continue ;
65
+
66
+ implementedHooks . Add ( hook ) ;
67
+ var attr = method . GetCustomAttributes ( true ) . OfType < LoadDatabaseValues > ( ) . SingleOrDefault ( ) ;
68
+ if ( attr != null )
63
69
{
64
- var method = targetType . GetMethod ( hook . ToString ( "G" ) ) ;
65
- if ( method . DeclaringType != parameterizedResourceDefinition )
70
+ if ( ! _databaseValuesAttributeAllowed . Contains ( hook ) )
66
71
{
67
- implementedHooks . Add ( hook ) ;
68
- var attr = method . GetCustomAttributes ( true ) . OfType < LoaDatabaseValues > ( ) . SingleOrDefault ( ) ;
69
- if ( attr != null )
70
- {
71
- if ( ! _databaseValuesAttributeAllowed . Contains ( hook ) )
72
- {
73
- throw new JsonApiSetupException ( $ "DatabaseValuesAttribute cannot be used on hook" +
74
- $ "{ hook . ToString ( "G" ) } in resource definition { parameterizedResourceDefinition . Name } ") ;
75
- }
76
- var targetList = attr . value ? enabledHooks : disabledHooks ;
77
- targetList . Add ( hook ) ;
78
- }
79
- }
72
+ throw new JsonApiSetupException ( $ "DatabaseValuesAttribute cannot be used on hook" +
73
+ $ "{ hook . ToString ( "G" ) } in resource definition { containerType . Name } ") ;
74
+ }
75
+ var targetList = attr . value ? databaseValuesEnabledHooks : databaseValuesDisabledHooks ;
76
+ targetList . Add ( hook ) ;
80
77
}
81
-
82
78
}
83
- ImplementedHooks = implementedHooks . ToArray ( ) ;
84
- DatabaseValuesDisabledHooks = disabledHooks . ToArray ( ) ;
85
- DatabaseValuesEnabledHooks = enabledHooks . ToArray ( ) ;
86
79
80
+ ImplementedHooks = implementedHooks . ToArray ( ) ;
81
+ DatabaseValuesDisabledHooks = databaseValuesDisabledHooks . ToArray ( ) ;
82
+ DatabaseValuesEnabledHooks = databaseValuesEnabledHooks . ToArray ( ) ;
87
83
}
88
84
}
89
- }
85
+ }
0 commit comments