2424using JsonApiDotNetCore . Serialization . Server . Builders ;
2525using JsonApiDotNetCore . Serialization . Server ;
2626using JsonApiDotNetCore . Serialization . Client ;
27- using JsonApiDotNetCore . Controllers ;
27+ using Microsoft . Extensions . DependencyInjection . Extensions ;
2828
2929namespace JsonApiDotNetCore . Extensions
3030{
3131 // ReSharper disable once InconsistentNaming
3232 public static class IServiceCollectionExtensions
3333 {
3434 static private readonly Action < JsonApiOptions > _noopConfig = opt => { } ;
35- static private JsonApiOptions _options { get { return new JsonApiOptions ( ) ; } }
3635 public static IServiceCollection AddJsonApi < TContext > ( this IServiceCollection services ,
3736 IMvcCoreBuilder mvcBuilder = null )
3837 where TContext : DbContext
@@ -48,25 +47,20 @@ public static IServiceCollection AddJsonApi<TContext>(this IServiceCollection se
4847 /// <param name="configureAction"></param>
4948 /// <returns></returns>
5049 public static IServiceCollection AddJsonApi < TContext > ( this IServiceCollection services ,
51- Action < JsonApiOptions > configureAction ,
50+ Action < JsonApiOptions > configureOptions ,
5251 IMvcCoreBuilder mvcBuilder = null )
5352 where TContext : DbContext
5453 {
55- var options = _options ;
54+ var options = new JsonApiOptions ( ) ;
5655 // add basic Mvc functionality
5756 mvcBuilder = mvcBuilder ?? services . AddMvcCore ( ) ;
58- // set standard options
59- configureAction ( options ) ;
60-
57+ // configures JsonApiOptions;
58+ configureOptions ( options ) ;
6159 // ResourceGraphBuilder should not be exposed on JsonApiOptions.
6260 // Instead, ResourceGraphBuilder should consume JsonApiOptions
63-
6461 // build the resource graph using ef core DbContext
6562 options . BuildResourceGraph ( builder => builder . AddDbContext < TContext > ( ) ) ;
66-
67- // add JsonApi fitlers and serializer
68- mvcBuilder . AddMvcOptions ( opt => AddMvcOptions ( opt , options ) ) ;
69-
63+ ConfigureMvc ( services , mvcBuilder , options ) ;
7064 // register services
7165 AddJsonApiInternals < TContext > ( services , options ) ;
7266 return services ;
@@ -83,13 +77,12 @@ public static IServiceCollection AddJsonApi(this IServiceCollection services,
8377 Action < JsonApiOptions > configureOptions ,
8478 IMvcCoreBuilder mvcBuilder = null )
8579 {
86- var options = _options ;
80+ var options = new JsonApiOptions ( ) ;
81+ // add basic Mvc functionality
8782 mvcBuilder = mvcBuilder ?? services . AddMvcCore ( ) ;
83+ // configures JsonApiOptions;
8884 configureOptions ( options ) ;
89-
90- // add JsonApi fitlers and serializer
91- mvcBuilder . AddMvcOptions ( opt => AddMvcOptions ( opt , options ) ) ;
92-
85+ ConfigureMvc ( services , mvcBuilder , options ) ;
9386 // register services
9487 AddJsonApiInternals ( services , options ) ;
9588 return services ;
@@ -107,22 +100,29 @@ public static IServiceCollection AddJsonApi(this IServiceCollection services,
107100 Action < ServiceDiscoveryFacade > autoDiscover ,
108101 IMvcCoreBuilder mvcBuilder = null )
109102 {
110- var options = _options ;
103+ var options = new JsonApiOptions ( ) ;
104+ // add basic Mvc functionality
111105 mvcBuilder = mvcBuilder ?? services . AddMvcCore ( ) ;
106+ // configures JsonApiOptions;
112107 configureOptions ( options ) ;
113-
114108 // build the resource graph using auto discovery.
115109 var facade = new ServiceDiscoveryFacade ( services , options . ResourceGraphBuilder ) ;
116110 autoDiscover ( facade ) ;
117-
118- // add JsonApi fitlers and serializer
119- mvcBuilder . AddMvcOptions ( opt => AddMvcOptions ( opt , options ) ) ;
120-
111+ ConfigureMvc ( services , mvcBuilder , options ) ;
121112 // register services
122113 AddJsonApiInternals ( services , options ) ;
123114 return services ;
124115 }
125116
117+ private static void ConfigureMvc ( IServiceCollection services , IMvcCoreBuilder mvcBuilder , JsonApiOptions options )
118+ {
119+ // add JsonApi filters and serializers
120+ mvcBuilder . AddMvcOptions ( opt => AddMvcOptions ( opt , options ) ) ;
121+ // register services that allow user to override behaviour that is configured on startup, like routing conventions
122+ AddStartupConfigurationServices ( services , options ) ;
123+ var intermediateProvider = services . BuildServiceProvider ( ) ;
124+ mvcBuilder . AddMvcOptions ( opt => opt . Conventions . Insert ( 0 , intermediateProvider . GetRequiredService < IJsonApiRoutingConvention > ( ) ) ) ;
125+ }
126126
127127 private static void AddMvcOptions ( MvcOptions options , JsonApiOptions config )
128128 {
@@ -143,11 +143,20 @@ public static void AddJsonApiInternals<TContext>(
143143 AddJsonApiInternals ( services , jsonApiOptions ) ;
144144 }
145145
146+ /// <summary>
147+ /// Adds services to the container that need to be retrieved with an intermediate provider during Startup.
148+ /// </summary>
149+ private static void AddStartupConfigurationServices ( this IServiceCollection services , JsonApiOptions jsonApiOptions )
150+ {
151+ services . AddSingleton < IJsonApiOptions > ( jsonApiOptions ) ;
152+ services . TryAddSingleton < IResourceNameFormatter > ( new KebabCaseFormatter ( ) ) ;
153+ services . TryAddSingleton < IJsonApiRoutingConvention , DefaultRoutingConvention > ( ) ;
154+ }
155+
146156 public static void AddJsonApiInternals (
147157 this IServiceCollection services ,
148158 JsonApiOptions jsonApiOptions )
149159 {
150-
151160 var graph = jsonApiOptions . ResourceGraph ?? jsonApiOptions . ResourceGraphBuilder . Build ( ) ;
152161
153162 if ( graph . UsesDbContext == false )
@@ -183,14 +192,12 @@ public static void AddJsonApiInternals(
183192 services . AddScoped ( typeof ( IResourceService < > ) , typeof ( EntityResourceService < > ) ) ;
184193 services . AddScoped ( typeof ( IResourceService < , > ) , typeof ( EntityResourceService < , > ) ) ;
185194
186- services . AddSingleton < IJsonApiOptions > ( jsonApiOptions ) ;
187195 services . AddSingleton < ILinksConfiguration > ( jsonApiOptions ) ;
188196 services . AddSingleton ( graph ) ;
189197 services . AddSingleton < IHttpContextAccessor , HttpContextAccessor > ( ) ;
190198 services . AddSingleton < IContextEntityProvider > ( graph ) ;
191199 services . AddScoped < ICurrentRequest , CurrentRequest > ( ) ;
192- services . AddScoped < IScopedServiceProvider , RequestScopedServiceProvider > ( ) ;
193- services . AddScoped < JsonApiRouteHandler > ( ) ;
200+ services . AddScoped < IScopedServiceProvider , RequestScopedServiceProvider > ( ) ;
194201 services . AddScoped < IJsonApiWriter , JsonApiWriter > ( ) ;
195202 services . AddScoped < IJsonApiReader , JsonApiReader > ( ) ;
196203 services . AddScoped < IGenericProcessorFactory , GenericProcessorFactory > ( ) ;
@@ -273,7 +280,6 @@ public static void SerializeAsJsonApi(this MvcOptions options, JsonApiOptions js
273280 {
274281 options . InputFormatters . Insert ( 0 , new JsonApiInputFormatter ( ) ) ;
275282 options . OutputFormatters . Insert ( 0 , new JsonApiOutputFormatter ( ) ) ;
276- options . Conventions . Insert ( 0 , new DasherizedRoutingConvention ( jsonApiOptions . Namespace ) ) ;
277283 }
278284
279285 /// <summary>
0 commit comments