26
26
using JsonApiDotNetCore . RequestServices . Contracts ;
27
27
using JsonApiDotNetCore . Services . Contract ;
28
28
using Microsoft . AspNetCore . Mvc ;
29
+ using Microsoft . Extensions . Logging ;
29
30
30
31
namespace JsonApiDotNetCore . Builders
31
32
{
@@ -37,17 +38,20 @@ internal sealed class JsonApiApplicationBuilder : IJsonApiApplicationBuilder
37
38
{
38
39
private readonly JsonApiOptions _options = new JsonApiOptions ( ) ;
39
40
private readonly IServiceCollection _services ;
40
- private IServiceDiscoveryFacade _serviceDiscoveryFacade ;
41
- private IResourceGraphBuilder _resourceGraphBuilder ;
42
41
private readonly IMvcCoreBuilder _mvcBuilder ;
43
- private ServiceProvider _intermediateServiceProvider ;
42
+ private readonly ResourceGraphBuilder _resourceGraphBuilder ;
43
+ private readonly ServiceDiscoveryFacade _serviceDiscoveryFacade ;
44
+ private readonly ServiceProvider _intermediateProvider ;
44
45
public Action < MvcOptions > ConfigureMvcOptions { get ; set ; }
45
46
46
- public JsonApiApplicationBuilder ( IServiceCollection services ,
47
- IMvcCoreBuilder mvcBuilder )
47
+ public JsonApiApplicationBuilder ( IServiceCollection services , IMvcCoreBuilder mvcBuilder )
48
48
{
49
49
_services = services ;
50
50
_mvcBuilder = mvcBuilder ;
51
+ _intermediateProvider = services . BuildServiceProvider ( ) ;
52
+ var loggerFactory = _intermediateProvider . GetService < ILoggerFactory > ( ) ;
53
+ _resourceGraphBuilder = new ResourceGraphBuilder ( _options , loggerFactory ) ;
54
+ _serviceDiscoveryFacade = new ServiceDiscoveryFacade ( _services , _resourceGraphBuilder , loggerFactory ) ;
51
55
}
52
56
53
57
/// <summary>
@@ -57,43 +61,30 @@ public void ConfigureJsonApiOptions(Action<JsonApiOptions> configureOptions)
57
61
{
58
62
configureOptions ? . Invoke ( _options ) ;
59
63
}
60
-
61
- /// <summary>
62
- /// Registers services that are required for the configuration of JsonApiDotNetCore during the start up.
63
- /// </summary>
64
- public void RegisterJsonApiStartupServices ( )
65
- {
66
- _services . AddSingleton < IJsonApiOptions > ( _options ) ;
67
- _services . TryAddSingleton < IJsonApiRoutingConvention , JsonApiRoutingConvention > ( ) ;
68
- _services . TryAddSingleton < IResourceGraphBuilder , ResourceGraphBuilder > ( ) ;
69
- _services . TryAddSingleton < IServiceDiscoveryFacade > ( sp =>
70
- new ServiceDiscoveryFacade ( _services , sp . GetRequiredService < IResourceGraphBuilder > ( ) ) ) ;
71
- }
72
-
73
- public void ConfigureAutoDiscovery ( Action < IServiceDiscoveryFacade > configureAutoDiscovery )
64
+
65
+ public void ConfigureAutoDiscovery ( Action < ServiceDiscoveryFacade > configureAutoDiscovery )
74
66
{
75
- var intermediateProvider = _services . BuildServiceProvider ( ) ;
76
- _serviceDiscoveryFacade = intermediateProvider . GetRequiredService < IServiceDiscoveryFacade > ( ) ;
77
- _resourceGraphBuilder = intermediateProvider . GetRequiredService < IResourceGraphBuilder > ( ) ;
78
- RegisterDiscoverableAssemblies ( configureAutoDiscovery , _serviceDiscoveryFacade ) ;
79
- _intermediateServiceProvider = intermediateProvider ;
67
+ configureAutoDiscovery ? . Invoke ( _serviceDiscoveryFacade ) ;
80
68
}
81
69
82
70
/// <summary>
83
71
/// Configures and build the resource graph with resources from the provided sources and adds it to the DI container.
84
72
/// </summary>
85
- public void AddResourceGraph ( Type dbContextType , Action < IResourceGraphBuilder > configureResources )
73
+ public void AddResourceGraph ( Type dbContextType , Action < ResourceGraphBuilder > configureResources )
86
74
{
87
75
AutoDiscoverResources ( _serviceDiscoveryFacade ) ;
88
- AddResourcesFromDbContext ( dbContextType , _intermediateServiceProvider , _resourceGraphBuilder ) ;
76
+ if ( dbContextType != null )
77
+ {
78
+ AddResourcesFromDbContext ( ( DbContext ) _intermediateProvider . GetService ( dbContextType ) , _resourceGraphBuilder ) ;
79
+ }
89
80
UserConfigureResources ( configureResources , _resourceGraphBuilder ) ;
90
81
_services . AddSingleton ( _resourceGraphBuilder . Build ( ) ) ;
91
82
}
92
83
93
84
/// <summary>
94
85
/// Configures built-in .NET Core MVC (things like middleware, routing). Most of this configuration can be adjusted for the developers' need.
95
86
/// Before calling .AddJsonApi(), a developer can register their own implementation of the following services to customize startup:
96
- /// <see cref="IResourceGraphBuilder "/>, <see cref="IServiceDiscoveryFacade "/>, <see cref="IJsonApiTypeMatchFilter"/>,
87
+ /// <see cref="ResourceGraphBuilder "/>, <see cref="ServiceDiscoveryFacade "/>, <see cref="IJsonApiTypeMatchFilter"/>,
97
88
/// <see cref="IJsonApiExceptionFilter"/> and <see cref="IJsonApiRoutingConvention"/>.
98
89
/// </summary>
99
90
public void ConfigureMvc ( )
@@ -104,9 +95,7 @@ public void ConfigureMvc()
104
95
options . Filters . AddService < IJsonApiExceptionFilter > ( ) ;
105
96
options . Filters . AddService < IJsonApiTypeMatchFilter > ( ) ;
106
97
options . Filters . AddService < IQueryStringActionFilter > ( ) ;
107
- options . Filters . Add ( new ConvertEmptyActionResultFilter ( ) ) ;
108
- options . InputFormatters . Insert ( 0 , new JsonApiInputFormatter ( ) ) ;
109
- options . OutputFormatters . Insert ( 0 , new JsonApiOutputFormatter ( ) ) ;
98
+ options . Filters . AddService < IConvertEmptyActionResultFilter > ( ) ;
110
99
ConfigureMvcOptions ? . Invoke ( options ) ;
111
100
} ) ;
112
101
@@ -122,7 +111,7 @@ public void ConfigureMvc()
122
111
public void DiscoverInjectables ( )
123
112
{
124
113
_serviceDiscoveryFacade . DiscoverInjectables ( ) ;
125
- _intermediateServiceProvider . Dispose ( ) ;
114
+ _intermediateProvider . Dispose ( ) ;
126
115
}
127
116
128
117
/// <summary>
@@ -143,27 +132,14 @@ public void ConfigureServices(Type dbContextType)
143
132
144
133
AddRepositoryLayer ( ) ;
145
134
AddServiceLayer ( ) ;
135
+ AddMiddlewareLayer ( ) ;
146
136
147
- _services . AddSingleton < IJsonApiApplicationBuilder > ( this ) ;
148
- _services . AddSingleton < IControllerResourceMapping > ( sp => sp . GetService < IJsonApiRoutingConvention > ( ) ) ;
149
-
150
- _services . TryAddSingleton < IExceptionHandler , ExceptionHandler > ( ) ;
151
- _services . TryAddScoped < IJsonApiExceptionFilter , JsonApiExceptionFilter > ( ) ;
152
- _services . TryAddScoped < IJsonApiTypeMatchFilter , JsonApiTypeMatchFilter > ( ) ;
153
- _services . TryAddScoped < IQueryStringActionFilter , QueryStringActionFilter > ( ) ;
154
-
155
- _services . AddSingleton < IHttpContextAccessor , HttpContextAccessor > ( ) ;
156
137
_services . AddSingleton < IResourceContextProvider > ( sp => sp . GetRequiredService < IResourceGraph > ( ) ) ;
157
138
158
- _services . AddScoped < ICurrentRequest , CurrentRequest > ( ) ;
159
139
_services . AddScoped < IScopedServiceProvider , RequestScopedServiceProvider > ( ) ;
160
- _services . AddScoped < IJsonApiWriter , JsonApiWriter > ( ) ;
161
- _services . AddScoped < IJsonApiReader , JsonApiReader > ( ) ;
162
140
_services . AddScoped < IGenericServiceFactory , GenericServiceFactory > ( ) ;
163
141
_services . AddScoped ( typeof ( RepositoryRelationshipUpdateHelper < > ) ) ;
164
- _services . AddScoped < ITargetedFields , TargetedFields > ( ) ;
165
142
_services . AddScoped < IResourceDefinitionProvider , ResourceDefinitionProvider > ( ) ;
166
- _services . AddScoped < IFieldsToSerialize , FieldsToSerialize > ( ) ;
167
143
_services . AddScoped ( typeof ( IResourceChangeTracker < > ) , typeof ( ResourceChangeTracker < > ) ) ;
168
144
_services . AddScoped < IResourceFactory , ResourceFactory > ( ) ;
169
145
_services . AddScoped < IPaginationContext , PaginationContext > ( ) ;
@@ -179,10 +155,25 @@ public void ConfigureServices(Type dbContextType)
179
155
_services . AddScoped < IInverseRelationships , InverseRelationships > ( ) ;
180
156
}
181
157
182
- private void RegisterDiscoverableAssemblies ( Action < IServiceDiscoveryFacade > configureAutoDiscovery ,
183
- IServiceDiscoveryFacade serviceDiscoveryFacade )
158
+ private void AddMiddlewareLayer ( )
184
159
{
185
- configureAutoDiscovery ? . Invoke ( serviceDiscoveryFacade ) ;
160
+ _services . AddSingleton < IJsonApiOptions > ( _options ) ;
161
+ _services . AddSingleton < IJsonApiApplicationBuilder > ( this ) ;
162
+ _services . TryAddSingleton < IExceptionHandler , ExceptionHandler > ( ) ;
163
+ _services . TryAddScoped < IJsonApiExceptionFilter , JsonApiExceptionFilter > ( ) ;
164
+ _services . TryAddScoped < IJsonApiTypeMatchFilter , JsonApiTypeMatchFilter > ( ) ;
165
+ _services . TryAddScoped < IQueryStringActionFilter , QueryStringActionFilter > ( ) ;
166
+ _services . TryAddScoped < IConvertEmptyActionResultFilter , ConvertEmptyActionResultFilter > ( ) ;
167
+ _services . TryAddSingleton < IJsonApiInputFormatter , JsonApiInputFormatter > ( ) ;
168
+ _services . TryAddSingleton < IJsonApiOutputFormatter , JsonApiOutputFormatter > ( ) ;
169
+ _services . TryAddSingleton < IJsonApiRoutingConvention , JsonApiRoutingConvention > ( ) ;
170
+ _services . AddSingleton < IControllerResourceMapping > ( sp => sp . GetService < IJsonApiRoutingConvention > ( ) ) ;
171
+ _services . AddSingleton < IHttpContextAccessor , HttpContextAccessor > ( ) ;
172
+ _services . AddScoped < ICurrentRequest , CurrentRequest > ( ) ;
173
+ _services . AddScoped < IJsonApiWriter , JsonApiWriter > ( ) ;
174
+ _services . AddScoped < IJsonApiReader , JsonApiReader > ( ) ;
175
+ _services . AddScoped < ITargetedFields , TargetedFields > ( ) ;
176
+ _services . AddScoped < IFieldsToSerialize , FieldsToSerialize > ( ) ;
186
177
}
187
178
188
179
private void AddRepositoryLayer ( )
@@ -284,33 +275,27 @@ private void AddServerSerialization()
284
275
_services . AddScoped < IResourceObjectBuilder , ResponseResourceObjectBuilder > ( ) ;
285
276
}
286
277
287
- private void AddResourcesFromDbContext ( Type dbContextType , ServiceProvider intermediateProvider ,
288
- IResourceGraphBuilder builder )
278
+ private void AddResourcesFromDbContext ( DbContext dbContext , ResourceGraphBuilder builder )
289
279
{
290
- if ( dbContextType != null )
280
+ foreach ( var entityType in dbContext . Model . GetEntityTypes ( ) )
291
281
{
292
- var dbContext = ( DbContext ) intermediateProvider . GetRequiredService ( dbContextType ) ;
293
-
294
- foreach ( var entityType in dbContext . Model . GetEntityTypes ( ) )
295
- {
296
- builder . AddResource ( entityType . ClrType ) ;
297
- }
282
+ builder . AddResource ( entityType . ClrType ) ;
298
283
}
299
284
}
300
285
301
286
/// <summary>
302
287
/// Performs auto-discovery of JsonApiDotNetCore services.
303
288
/// </summary>
304
- private void AutoDiscoverResources ( IServiceDiscoveryFacade serviceDiscoveryFacade )
289
+ private void AutoDiscoverResources ( ServiceDiscoveryFacade serviceDiscoveryFacade )
305
290
{
306
291
serviceDiscoveryFacade . DiscoverResources ( ) ;
307
292
}
308
293
309
294
/// <summary>
310
- /// Executes the action provided by the user to configure the resources using <see cref="IResourceGraphBuilder "/>
295
+ /// Executes the action provided by the user to configure the resources using <see cref="ResourceGraphBuilder "/>
311
296
/// </summary>
312
- private void UserConfigureResources ( Action < IResourceGraphBuilder > configureResources ,
313
- IResourceGraphBuilder resourceGraphBuilder )
297
+ private void UserConfigureResources ( Action < ResourceGraphBuilder > configureResources ,
298
+ ResourceGraphBuilder resourceGraphBuilder )
314
299
{
315
300
configureResources ? . Invoke ( resourceGraphBuilder ) ;
316
301
}
0 commit comments