diff --git a/src/Volo.Abp.AspNetCore.Mvc/Microsoft/Extensions/DependencyInjection/AbpApiVersioningOptionsExtensions.cs b/src/Volo.Abp.AspNetCore.Mvc/Microsoft/Extensions/DependencyInjection/AbpApiVersioningOptionsExtensions.cs index d72ec24d95..689b378255 100644 --- a/src/Volo.Abp.AspNetCore.Mvc/Microsoft/Extensions/DependencyInjection/AbpApiVersioningOptionsExtensions.cs +++ b/src/Volo.Abp.AspNetCore.Mvc/Microsoft/Extensions/DependencyInjection/AbpApiVersioningOptionsExtensions.cs @@ -1,5 +1,5 @@ -using System.Reflection; -using Microsoft.AspNetCore.Mvc; +using System.Linq; +using System.Reflection; using Microsoft.AspNetCore.Mvc.Versioning; using Microsoft.AspNetCore.Mvc.Versioning.Conventions; using Volo.Abp.AspNetCore.Mvc; @@ -8,26 +8,57 @@ namespace Microsoft.Extensions.DependencyInjection { public static class AbpApiVersioningOptionsExtensions { - public static void AddAbpModules(this ApiVersioningOptions options, IServiceCollection services) + public static void ConfigureAbpModules(this ApiVersioningOptions options, IServiceCollection services) { + //TODO: Use new builder will be released with Api Versioning 2.1 instead of reflection! + services.Configure(op => { + //TODO: Configuring api version should be done directly inside ConfigureAbpModules, + //TODO: not in a callback that will be called by MVC later! For that, we immediately need to controllerAssemblySettings + foreach (var setting in op.AppServiceControllers.ControllerAssemblySettings) { - foreach (var controllerType in setting.ControllerTypes) + if (setting.ApiVersionConfigurer == null) + { + ConfigureApiVersionsByConvention(options, setting); + } + else { - var controllerBuilder = typeof(ApiVersionConventionBuilder) - .GetMethod(nameof(ApiVersionConventionBuilder.Controller), BindingFlags.Instance | BindingFlags.Public) - .MakeGenericMethod(controllerType) - .Invoke(options.Conventions, null); + setting.ApiVersionConfigurer.Invoke(options); + } + } + }); + } + private static void ConfigureApiVersionsByConvention(ApiVersioningOptions options, AbpControllerAssemblySetting setting) + { + foreach (var controllerType in setting.ControllerTypes) + { + var controllerBuilder = typeof(ApiVersionConventionBuilder) + .GetMethod(nameof(ApiVersionConventionBuilder.Controller), + BindingFlags.Instance | BindingFlags.Public) + .MakeGenericMethod(controllerType) + .Invoke(options.Conventions, null); + + if (setting.ApiVersions.Any()) + { + foreach (var apiVersion in setting.ApiVersions) + { typeof(ControllerApiVersionConventionBuilder<>) .MakeGenericType(controllerType) .GetMethod("HasApiVersion") - .Invoke(controllerBuilder, new object[] { setting.ApiVersion }); + .Invoke(controllerBuilder, new object[] {apiVersion}); } } - }); + else + { + typeof(ControllerApiVersionConventionBuilder<>) + .MakeGenericType(controllerType) + .GetMethod("IsApiVersionNeutral") + .Invoke(controllerBuilder, null); + } + } } } } diff --git a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcOptions.cs b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcOptions.cs index 781824846a..7d2bb24341 100644 --- a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcOptions.cs +++ b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcOptions.cs @@ -2,6 +2,7 @@ { public class AbpAspNetCoreMvcOptions { + //TODO: Rename to ConventionalControllers public AppServiceControllerOptions AppServiceControllers { get; } public AbpAspNetCoreMvcOptions() diff --git a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpControllerAssemblySetting.cs b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpControllerAssemblySetting.cs index a99b87855e..ffe510eaaa 100644 --- a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpControllerAssemblySetting.cs +++ b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpControllerAssemblySetting.cs @@ -5,6 +5,7 @@ using System.Reflection; using JetBrains.Annotations; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ApplicationModels; +using Microsoft.AspNetCore.Mvc.Versioning; using Volo.Abp.Application.Services; using Volo.Abp.Reflection; @@ -42,7 +43,10 @@ namespace Volo.Abp.AspNetCore.Mvc [CanBeNull] public Func UrlActionNameNormalizer { get; set; } - public ApiVersion ApiVersion { get; set; } + public List ApiVersions { get; set; } + + public Action ApiVersionConfigurer { get; set; } + public AbpControllerAssemblySetting([NotNull] Assembly assembly, [NotNull] string rootPath) { @@ -53,7 +57,7 @@ namespace Volo.Abp.AspNetCore.Mvc ControllerTypes = new HashSet(); - ApiVersion = new ApiVersion(1, 0); + ApiVersions = new List(); } public void Initialize() diff --git a/src/Volo.Abp.Identity.HttpApi.Host/AbpIdentityHttpApiHostModule.cs b/src/Volo.Abp.Identity.HttpApi.Host/AbpIdentityHttpApiHostModule.cs index 01b14f1216..c171b4fa93 100644 --- a/src/Volo.Abp.Identity.HttpApi.Host/AbpIdentityHttpApiHostModule.cs +++ b/src/Volo.Abp.Identity.HttpApi.Host/AbpIdentityHttpApiHostModule.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Reflection; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; @@ -32,6 +33,8 @@ namespace Volo.Abp.Identity.HttpApi.Host var hostingEnvironment = services.GetSingletonInstance(); //TOD: Move to BuildConfiguration method var configuration = BuildConfiguration(hostingEnvironment); + services.AddOptions(); //TODO: Remove later, for test purposes + services.Configure(configuration); services.Configure(options => @@ -55,7 +58,8 @@ namespace Volo.Abp.Identity.HttpApi.Host services.AddApiVersioning(o => { o.ReportApiVersions = true; - o.Conventions.Controller().IsApiVersionNeutral(); + o.Conventions.Controller().IsApiVersionNeutral(); //TODO: This should be inside the framework! + //o.Conventions.Controller().Action((MethodInfo)null).MapToApiVersion(new ApiVersion(1,1),).IsApiVersionNeutral(); //o.Conventions.Controller().HasApiVersion(new ApiVersion(3, 0)); //We can do that based on controller's AbpApiVersion attribute! o.AssumeDefaultVersionWhenUnspecified = true; o.DefaultApiVersion = new ApiVersion(3, 0); //Default: 1.0 //We can not rely on that, application should do. @@ -65,7 +69,7 @@ namespace Volo.Abp.Identity.HttpApi.Host //o.Conventions.Controller().HasApiVersion(2, 0); //o.Conventions.Controller().IsApiVersionNeutral(); - o.AddAbpModules(services); + o.ConfigureAbpModules(services); }); services.AddSwaggerGen( diff --git a/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/AbpIdentityHttpApiModule.cs b/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/AbpIdentityHttpApiModule.cs index f452e08507..195ce009b7 100644 --- a/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/AbpIdentityHttpApiModule.cs +++ b/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/AbpIdentityHttpApiModule.cs @@ -1,4 +1,5 @@ using System; +using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.Modularity; @@ -18,11 +19,11 @@ namespace Volo.Abp.Identity { opts.RootPath = "identity"; opts.UrlControllerNameNormalizer = context => context.ControllerName.RemovePreFix("Identity"); + opts.ApiVersions.Add(new ApiVersion(2, 0)); }); - }); - //TODO: Allow to use Api Versioning's API to explicitly configure versioning for app services and other controllers, - //TODO: rather than implicitly doing it via AppServiceControllers.Create call above! + options.AppServiceControllers.Create(typeof(AbpIdentityHttpApiModule).Assembly); + }); } } } \ No newline at end of file diff --git a/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/FixtureController.cs b/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/FixtureController.cs new file mode 100644 index 0000000000..cd12153418 --- /dev/null +++ b/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/FixtureController.cs @@ -0,0 +1,31 @@ +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.Application.Services; +using Volo.Abp.AspNetCore.Mvc; + +namespace Volo.Abp.Identity +{ + //TODO: This is just a test controller and will be removed lster + [Route("api/identity/fixture")] + [ApiVersion("2.0", Deprecated = true)] + [ApiVersion("3.0")] + public class FixtureController : AbpController, IRemoteService + { + [HttpGet] + public int Get() + { + return 42; + } + + [HttpGet, MapToApiVersion("3.0")] + public int Get3() + { + return 42; + } + + [HttpPost] + public int Post() + { + return 42; + } + } +} \ No newline at end of file