diff --git a/docs/getting-started/step-by-step.md b/docs/getting-started/step-by-step.md index 732b15924e..ac0b03fc74 100644 --- a/docs/getting-started/step-by-step.md +++ b/docs/getting-started/step-by-step.md @@ -96,14 +96,15 @@ public void ConfigureServices(IServiceCollection services) } ``` -Add the middleware to the Startup.Configure method. Note that under the hood, -this will call `app.UseRouting()` and `app.UseEndpoints(...)` so there is no need to add that as well. +Add the middleware to the Startup.Configure method. ```c# // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app) { + app.UseRouting(); app.UseJsonApi(); + app.UseEndpoints(endpoints => endpoints.MapControllers()); } ``` @@ -125,7 +126,9 @@ public void Configure(IApplicationBuilder app, AppDbContext context) context.SaveChanges(); } + app.UseRouting(); app.UseJsonApi(); + app.UseEndpoints(endpoints => endpoints.MapControllers()); } ``` @@ -135,4 +138,3 @@ public void Configure(IApplicationBuilder app, AppDbContext context) dotnet run curl http://localhost:5000/people ``` - diff --git a/docs/usage/extensibility/middleware.md b/docs/usage/extensibility/middleware.md index 15e4854b60..dc1c7a6e23 100644 --- a/docs/usage/extensibility/middleware.md +++ b/docs/usage/extensibility/middleware.md @@ -5,9 +5,10 @@ Add the following to your Startup.ConfigureServices method. Replace AppDbContext services.AddJsonApi(); ``` -Add the middleware to the Startup.Configure method. Note that under the hood, -this will call `app.UseRouting()` and `app.UseEndpoints(...)` so there is no need to add that as well. +Add the middleware to the Startup.Configure method. ```c3 +app.UseRouting(); app.UseJsonApi(); +app.UseEndpoints(endpoints => endpoints.MapControllers()); ``` diff --git a/src/Examples/GettingStarted/Startup.cs b/src/Examples/GettingStarted/Startup.cs index 5a59ba2514..dd499af5ba 100644 --- a/src/Examples/GettingStarted/Startup.cs +++ b/src/Examples/GettingStarted/Startup.cs @@ -9,7 +9,7 @@ namespace GettingStarted { public sealed class Startup { - // This method gets called by the runtime. Use this method to add services to the container. + // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddDbContext( @@ -19,14 +19,16 @@ public void ConfigureServices(IServiceCollection services) options => options.Namespace = "api"); } - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, SampleDbContext context) { context.Database.EnsureDeleted(); context.Database.EnsureCreated(); CreateSampleData(context); + app.UseRouting(); app.UseJsonApi(); + app.UseEndpoints(endpoints => endpoints.MapControllers()); } private static void CreateSampleData(SampleDbContext context) diff --git a/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs b/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs index 169d01e99a..292dd9019b 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Startups/Startup.cs @@ -73,7 +73,10 @@ public void Configure( AppDbContext context) { context.Database.EnsureCreated(); + + app.UseRouting(); app.UseJsonApi(); + app.UseEndpoints(endpoints => endpoints.MapControllers()); } } } diff --git a/src/Examples/NoEntityFrameworkExample/Startup.cs b/src/Examples/NoEntityFrameworkExample/Startup.cs index bdcbea066c..ef3bcb5287 100644 --- a/src/Examples/NoEntityFrameworkExample/Startup.cs +++ b/src/Examples/NoEntityFrameworkExample/Startup.cs @@ -43,7 +43,9 @@ public void Configure(IApplicationBuilder app, AppDbContext context) { context.Database.EnsureCreated(); + app.UseRouting(); app.UseJsonApi(); + app.UseEndpoints(endpoints => endpoints.MapControllers()); } } } diff --git a/src/JsonApiDotNetCore/Builders/JsonApiApplicationBuilder.cs b/src/JsonApiDotNetCore/Builders/JsonApiApplicationBuilder.cs index 1cba573b06..f542ba40e3 100644 --- a/src/JsonApiDotNetCore/Builders/JsonApiApplicationBuilder.cs +++ b/src/JsonApiDotNetCore/Builders/JsonApiApplicationBuilder.cs @@ -62,16 +62,22 @@ public void ConfigureMvc(Type dbContextType) { RegisterJsonApiStartupServices(); - var intermediateProvider = _services.BuildServiceProvider(); - _resourceGraphBuilder = intermediateProvider.GetRequiredService(); - _serviceDiscoveryFacade = intermediateProvider.GetRequiredService(); - _dbContextType = dbContextType; + IJsonApiExceptionFilterProvider exceptionFilterProvider; + IJsonApiTypeMatchFilterProvider typeMatchFilterProvider; + IJsonApiRoutingConvention routingConvention; - AddResourceTypesFromDbContext(intermediateProvider); + using (var intermediateProvider = _services.BuildServiceProvider()) + { + _resourceGraphBuilder = intermediateProvider.GetRequiredService(); + _serviceDiscoveryFacade = intermediateProvider.GetRequiredService(); + _dbContextType = dbContextType; + + AddResourceTypesFromDbContext(intermediateProvider); - var exceptionFilterProvider = intermediateProvider.GetRequiredService(); - var typeMatchFilterProvider = intermediateProvider.GetRequiredService(); - var routingConvention = intermediateProvider.GetRequiredService(); + exceptionFilterProvider = intermediateProvider.GetRequiredService(); + typeMatchFilterProvider = intermediateProvider.GetRequiredService(); + routingConvention = intermediateProvider.GetRequiredService(); + } _mvcBuilder.AddMvcOptions(options => { diff --git a/src/JsonApiDotNetCore/Extensions/ApplicationBuilderExtensions.cs b/src/JsonApiDotNetCore/Extensions/ApplicationBuilderExtensions.cs index 9c177053de..8d943101e0 100644 --- a/src/JsonApiDotNetCore/Extensions/ApplicationBuilderExtensions.cs +++ b/src/JsonApiDotNetCore/Extensions/ApplicationBuilderExtensions.cs @@ -1,61 +1,26 @@ -using JsonApiDotNetCore.Internal; using JsonApiDotNetCore.Middleware; using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; namespace JsonApiDotNetCore { public static class ApplicationBuilderExtensions { /// - /// Validates the resource graph and optionally registers the JsonApiDotNetCore middleware. + /// Registers the JsonApiDotNetCore middleware. /// - /// - /// The can be used to skip any middleware registration, in which case the developer - /// is responsible for registering required middleware. - /// - /// - /// Indicates to not register any middleware. This enables callers to take full control of middleware registration order. - /// Indicates if 'app.UseAuthentication()' should be called. Ignored when is set to true. - /// Indicates if 'app.UseAuthorization()' should be called. Ignored when is set to true. + /// The to add the middleware to. /// - /// The next example illustrates how to manually register middleware. - /// - /// app.UseJsonApi(skipRegisterMiddleware: true); + /// The code below is the minimal that is required for proper activation, + /// which should be added to your Startup.Configure method. + /// endpoints.MapControllers()); - /// + /// ]]> /// - public static void UseJsonApi(this IApplicationBuilder app, bool skipRegisterMiddleware = false, bool useAuthentication = false, bool useAuthorization = false) + public static void UseJsonApi(this IApplicationBuilder builder) { - using (var scope = app.ApplicationServices.CreateScope()) - { - var inverseRelationshipResolver = scope.ServiceProvider.GetService(); - inverseRelationshipResolver?.Resolve(); - } - - if (!skipRegisterMiddleware) - { - // An endpoint is selected and set on the HttpContext if a match is found - app.UseRouting(); - - if (useAuthentication) - { - app.UseAuthentication(); - } - - if (useAuthorization) - { - app.UseAuthorization(); - } - - // middleware to run after routing occurs. - app.UseMiddleware(); - - // Executes the endpoints that was selected by routing. - app.UseEndpoints(endpoints => endpoints.MapControllers()); - } + builder.UseMiddleware(); } } } diff --git a/src/JsonApiDotNetCore/Extensions/ServiceCollectionExtensions.cs b/src/JsonApiDotNetCore/Extensions/ServiceCollectionExtensions.cs index 1fb4a3fb8d..ea460c8a5d 100644 --- a/src/JsonApiDotNetCore/Extensions/ServiceCollectionExtensions.cs +++ b/src/JsonApiDotNetCore/Extensions/ServiceCollectionExtensions.cs @@ -26,6 +26,8 @@ public static IServiceCollection AddJsonApi(this IServiceCollection services, IMvcCoreBuilder mvcBuilder = null) { SetupApplicationBuilder(services, options, discovery, resources, mvcBuilder, null); + ResolveInverseRelationships(services); + return services; } @@ -40,6 +42,8 @@ public static IServiceCollection AddJsonApi(this IServiceCollection where TDbContext : DbContext { SetupApplicationBuilder(services, options, discovery, resources, mvcBuilder, typeof(TDbContext)); + ResolveInverseRelationships(services); + return services; } @@ -56,6 +60,15 @@ private static void SetupApplicationBuilder(IServiceCollection services, Action< applicationBuilder.ConfigureServices(); } + private static void ResolveInverseRelationships(IServiceCollection services) + { + using var intermediateProvider = services.BuildServiceProvider(); + using var scope = intermediateProvider.CreateScope(); + + var inverseRelationshipResolver = scope.ServiceProvider.GetService(); + inverseRelationshipResolver?.Resolve(); + } + /// /// Enables client serializers for sending requests and receiving responses /// in json:api format. Internally only used for testing.