Allow to specify more than one api version for services.

pull/122/head
Halil İbrahim Kalkan 7 years ago
parent 1b9c2974ac
commit e511f8a0f2

@ -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<AbpAspNetCoreMvcOptions>(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);
}
}
}
}
}

@ -2,6 +2,7 @@
{
public class AbpAspNetCoreMvcOptions
{
//TODO: Rename to ConventionalControllers
public AppServiceControllerOptions AppServiceControllers { get; }
public AbpAspNetCoreMvcOptions()

@ -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<UrlActionNameNormalizerContext, string> UrlActionNameNormalizer { get; set; }
public ApiVersion ApiVersion { get; set; }
public List<ApiVersion> ApiVersions { get; set; }
public Action<ApiVersioningOptions> ApiVersionConfigurer { get; set; }
public AbpControllerAssemblySetting([NotNull] Assembly assembly, [NotNull] string rootPath)
{
@ -53,7 +57,7 @@ namespace Volo.Abp.AspNetCore.Mvc
ControllerTypes = new HashSet<Type>();
ApiVersion = new ApiVersion(1, 0);
ApiVersions = new List<ApiVersion>();
}
public void Initialize()

@ -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<IHostingEnvironment>(); //TOD: Move to BuildConfiguration method
var configuration = BuildConfiguration(hostingEnvironment);
services.AddOptions(); //TODO: Remove later, for test purposes
services.Configure<DbConnectionOptions>(configuration);
services.Configure<AbpDbContextOptions>(options =>
@ -55,7 +58,8 @@ namespace Volo.Abp.Identity.HttpApi.Host
services.AddApiVersioning(o =>
{
o.ReportApiVersions = true;
o.Conventions.Controller<AbpApiDefinitionController>().IsApiVersionNeutral();
o.Conventions.Controller<AbpApiDefinitionController>().IsApiVersionNeutral(); //TODO: This should be inside the framework!
//o.Conventions.Controller<AbpApiDefinitionController>().Action((MethodInfo)null).MapToApiVersion(new ApiVersion(1,1),).IsApiVersionNeutral();
//o.Conventions.Controller<AbpApiDefinitionController>().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<IdentityUserAppService>().HasApiVersion(2, 0);
//o.Conventions.Controller<IdentityRoleAppService>().IsApiVersionNeutral();
o.AddAbpModules(services);
o.ConfigureAbpModules(services);
});
services.AddSwaggerGen(

@ -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);
});
}
}
}

@ -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;
}
}
}
Loading…
Cancel
Save