2323namespace JsonApiDotNetCore . Configuration ;
2424
2525/// <summary>
26- /// A utility class that builds a JsonApi application. It registers all required services and allows the user to override parts of the startup
26+ /// A utility class that builds a JSON:API application. It registers all required services and allows the user to override parts of the startup
2727/// configuration.
2828/// </summary>
29- internal sealed class JsonApiApplicationBuilder : IJsonApiApplicationBuilder , IDisposable
29+ internal sealed class JsonApiApplicationBuilder : IJsonApiApplicationBuilder
3030{
31- private readonly JsonApiOptions _options = new ( ) ;
3231 private readonly IServiceCollection _services ;
3332 private readonly IMvcCoreBuilder _mvcBuilder ;
34- private readonly ResourceGraphBuilder _resourceGraphBuilder ;
35- private readonly ServiceDiscoveryFacade _serviceDiscoveryFacade ;
36- private readonly ServiceProvider _intermediateProvider ;
33+ private readonly JsonApiOptions _options = new ( ) ;
34+ private readonly ResourceDescriptorAssemblyCache _assemblyCache = new ( ) ;
3735
3836 public Action < MvcOptions > ? ConfigureMvcOptions { get ; set ; }
3937
@@ -44,12 +42,6 @@ public JsonApiApplicationBuilder(IServiceCollection services, IMvcCoreBuilder mv
4442
4543 _services = services ;
4644 _mvcBuilder = mvcBuilder ;
47- _intermediateProvider = services . BuildServiceProvider ( ) ;
48-
49- var loggerFactory = _intermediateProvider . GetRequiredService < ILoggerFactory > ( ) ;
50-
51- _resourceGraphBuilder = new ResourceGraphBuilder ( _options , loggerFactory ) ;
52- _serviceDiscoveryFacade = new ServiceDiscoveryFacade ( _services , _resourceGraphBuilder , loggerFactory ) ;
5345 }
5446
5547 /// <summary>
@@ -61,35 +53,51 @@ public void ConfigureJsonApiOptions(Action<JsonApiOptions>? configureOptions)
6153 }
6254
6355 /// <summary>
64- /// Executes the action provided by the user to configure <see cref="ServiceDiscoveryFacade" /> .
56+ /// Executes the action provided by the user to configure auto-discovery .
6557 /// </summary>
6658 public void ConfigureAutoDiscovery ( Action < ServiceDiscoveryFacade > ? configureAutoDiscovery )
6759 {
68- configureAutoDiscovery ? . Invoke ( _serviceDiscoveryFacade ) ;
60+ if ( configureAutoDiscovery != null )
61+ {
62+ var facade = new ServiceDiscoveryFacade ( _assemblyCache ) ;
63+ configureAutoDiscovery . Invoke ( facade ) ;
64+ }
6965 }
7066
7167 /// <summary>
72- /// Configures and builds the resource graph with resources from the provided sources and adds it to the DI container.
68+ /// Configures and builds the resource graph with resources from the provided sources and adds them to the IoC container.
7369 /// </summary>
7470 public void ConfigureResourceGraph ( ICollection < Type > dbContextTypes , Action < ResourceGraphBuilder > ? configureResourceGraph )
7571 {
7672 ArgumentGuard . NotNull ( dbContextTypes ) ;
7773
78- _serviceDiscoveryFacade . DiscoverResources ( ) ;
79-
80- foreach ( Type dbContextType in dbContextTypes )
74+ _services . TryAddSingleton ( serviceProvider =>
8175 {
82- var dbContext = ( DbContext ) _intermediateProvider . GetRequiredService ( dbContextType ) ;
83- _resourceGraphBuilder . Add ( dbContext ) ;
84- }
76+ var loggerFactory = serviceProvider . GetRequiredService < ILoggerFactory > ( ) ;
77+ var resourceGraphBuilder = new ResourceGraphBuilder ( _options , loggerFactory ) ;
8578
86- configureResourceGraph ? . Invoke ( _resourceGraphBuilder ) ;
79+ var scanner = new ResourcesAssemblyScanner ( _assemblyCache , resourceGraphBuilder ) ;
80+ scanner . DiscoverResources ( ) ;
8781
88- IResourceGraph resourceGraph = _resourceGraphBuilder . Build ( ) ;
82+ if ( dbContextTypes . Count > 0 )
83+ {
84+ using IServiceScope scope = serviceProvider . CreateScope ( ) ;
8985
90- _options . SerializerOptions . Converters . Add ( new ResourceObjectConverter ( resourceGraph ) ) ;
86+ foreach ( Type dbContextType in dbContextTypes )
87+ {
88+ var dbContext = ( DbContext ) scope . ServiceProvider . GetRequiredService ( dbContextType ) ;
89+ resourceGraphBuilder . Add ( dbContext ) ;
90+ }
91+ }
92+
93+ configureResourceGraph ? . Invoke ( resourceGraphBuilder ) ;
94+
95+ IResourceGraph resourceGraph = resourceGraphBuilder . Build ( ) ;
96+
97+ _options . SerializerOptions . Converters . Add ( new ResourceObjectConverter ( resourceGraph ) ) ;
9198
92- _services . TryAddSingleton ( resourceGraph ) ;
99+ return resourceGraph ;
100+ } ) ;
93101 }
94102
95103 /// <summary>
@@ -114,15 +122,16 @@ public void ConfigureMvc()
114122 }
115123
116124 /// <summary>
117- /// Discovers DI registrable services in the assemblies marked for discovery.
125+ /// Registers injectables in the IoC container found in assemblies marked for auto- discovery.
118126 /// </summary>
119127 public void DiscoverInjectables ( )
120128 {
121- _serviceDiscoveryFacade . DiscoverInjectables ( ) ;
129+ var scanner = new InjectablesAssemblyScanner ( _assemblyCache , _services ) ;
130+ scanner . DiscoverInjectables ( ) ;
122131 }
123132
124133 /// <summary>
125- /// Registers the remaining internals.
134+ /// Registers the remaining internals in the IoC container .
126135 /// </summary>
127136 public void ConfigureServiceContainer ( ICollection < Type > dbContextTypes )
128137 {
@@ -182,15 +191,15 @@ private void AddMiddlewareLayer()
182191
183192 private void AddResourceLayer ( )
184193 {
185- RegisterImplementationForInterfaces ( ServiceDiscoveryFacade . ResourceDefinitionUnboundInterfaces , typeof ( JsonApiResourceDefinition < , > ) ) ;
194+ RegisterImplementationForInterfaces ( InjectablesAssemblyScanner . ResourceDefinitionUnboundInterfaces , typeof ( JsonApiResourceDefinition < , > ) ) ;
186195
187196 _services . TryAddScoped < IResourceDefinitionAccessor , ResourceDefinitionAccessor > ( ) ;
188197 _services . TryAddScoped < IResourceFactory , ResourceFactory > ( ) ;
189198 }
190199
191200 private void AddRepositoryLayer ( )
192201 {
193- RegisterImplementationForInterfaces ( ServiceDiscoveryFacade . RepositoryUnboundInterfaces , typeof ( EntityFrameworkCoreRepository < , > ) ) ;
202+ RegisterImplementationForInterfaces ( InjectablesAssemblyScanner . RepositoryUnboundInterfaces , typeof ( EntityFrameworkCoreRepository < , > ) ) ;
194203
195204 _services . TryAddScoped < IResourceRepositoryAccessor , ResourceRepositoryAccessor > ( ) ;
196205
@@ -204,7 +213,7 @@ private void AddRepositoryLayer()
204213
205214 private void AddServiceLayer ( )
206215 {
207- RegisterImplementationForInterfaces ( ServiceDiscoveryFacade . ServiceUnboundInterfaces , typeof ( JsonApiResourceService < , > ) ) ;
216+ RegisterImplementationForInterfaces ( InjectablesAssemblyScanner . ServiceUnboundInterfaces , typeof ( JsonApiResourceService < , > ) ) ;
208217 }
209218
210219 private void RegisterImplementationForInterfaces ( HashSet < Type > unboundInterfaces , Type unboundImplementationType )
@@ -291,9 +300,4 @@ private void AddOperationsLayer()
291300 _services . TryAddScoped < IOperationProcessorAccessor , OperationProcessorAccessor > ( ) ;
292301 _services . TryAddScoped < ILocalIdTracker , LocalIdTracker > ( ) ;
293302 }
294-
295- public void Dispose ( )
296- {
297- _intermediateProvider . Dispose ( ) ;
298- }
299303}
0 commit comments