diff --git a/Directory.Packages.props b/Directory.Packages.props
index ca6058bed5..53a7f30cbb 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -11,7 +11,8 @@
-
+
+
diff --git a/docs/en/API/API-Versioning.md b/docs/en/API/API-Versioning.md
index d0f94f2259..741eafbb75 100644
--- a/docs/en/API/API-Versioning.md
+++ b/docs/en/API/API-Versioning.md
@@ -8,11 +8,10 @@ ABP Framework integrates the [ASPNET-API-Versioning](https://github.com/dotnet/a
```cs
public override void ConfigureServices(ServiceConfigurationContext context)
{
+ // Show neutral/versionless APIs.
+ context.Services.AddTransient();
context.Services.AddAbpApiVersioning(options =>
{
- // Show neutral/versionless APIs.
- options.UseApiBehavior = false;
-
options.ReportApiVersions = true;
options.AssumeDefaultVersionWhenUnspecified = true;
});
@@ -239,11 +238,10 @@ public override void ConfigureServices(ServiceConfigurationContext context)
preActions.Configure(options);
});
+ // Show neutral/versionless APIs.
+ context.Services.AddTransient();
context.Services.AddAbpApiVersioning(options =>
{
- // Show neutral/versionless APIs.
- options.UseApiBehavior = false;
-
options.ReportApiVersions = true;
options.AssumeDefaultVersionWhenUnspecified = true;
@@ -263,27 +261,22 @@ public override void ConfigureServices(ServiceConfigurationContext context)
public override void ConfigureServices(ServiceConfigurationContext context)
{
+ // Show neutral/versionless APIs.
+ context.Services.AddTransient();
context.Services.AddAbpApiVersioning(options =>
{
- // Show neutral/versionless APIs.
- options.UseApiBehavior = false;
-
options.ReportApiVersions = true;
options.AssumeDefaultVersionWhenUnspecified = true;
+ }).AddApiExplorer(options => {
+ // add the versioned api explorer, which also adds IApiVersionDescriptionProvider service
+ // note: the specified format code will format the version as "'v'major[.minor][-status]"
+ options.GroupNameFormat = "'v'VVV";
+
+ // note: this option is only necessary when versioning by url segment. the SubstitutionFormat
+ // can also be used to control the format of the API version in route templates
+ options.SubstituteApiVersionInUrl = true;
});
- context.Services.AddVersionedApiExplorer(
- options =>
- {
- // add the versioned api explorer, which also adds IApiVersionDescriptionProvider service
- // note: the specified format code will format the version as "'v'major[.minor][-status]"
- options.GroupNameFormat = "'v'VVV";
-
- // note: this option is only necessary when versioning by url segment. the SubstitutionFormat
- // can also be used to control the format of the API version in route templates
- options.SubstituteApiVersionInUrl = true;
- });
-
context.Services.AddTransient, ConfigureSwaggerOptions>();
context.Services.AddAbpSwaggerGen(
@@ -322,7 +315,7 @@ public override void OnApplicationInitialization(ApplicationInitializationContex
app.UseAbpRequestLocalization();
app.UseSwagger();
- app.UseSwaggerUI(
+ app.UseAbpSwaggerUI(
options =>
{
var provider = app.ApplicationServices.GetRequiredService();
diff --git a/docs/zh-Hans/API/API-Versioning.md b/docs/zh-Hans/API/API-Versioning.md
index 81bb6574c6..3e63ec045e 100644
--- a/docs/zh-Hans/API/API-Versioning.md
+++ b/docs/zh-Hans/API/API-Versioning.md
@@ -7,11 +7,10 @@ ABP框架集成了[ASPNET-API-版本控制](https://github.com/dotnet/aspnet-api
```cs
public override void ConfigureServices(ServiceConfigurationContext context)
{
+ // Show neutral/versionless APIs.
+ context.Services.AddTransient();
context.Services.AddAbpApiVersioning(options =>
{
- // Show neutral/versionless APIs.
- options.UseApiBehavior = false;
-
options.ReportApiVersions = true;
options.AssumeDefaultVersionWhenUnspecified = true;
});
@@ -238,11 +237,10 @@ public override void ConfigureServices(ServiceConfigurationContext context)
preActions.Configure(options);
});
+ // Show neutral/versionless APIs.
+ context.Services.AddTransient();
context.Services.AddAbpApiVersioning(options =>
{
- // Show neutral/versionless APIs.
- options.UseApiBehavior = false;
-
options.ReportApiVersions = true;
options.AssumeDefaultVersionWhenUnspecified = true;
@@ -262,27 +260,22 @@ public override void ConfigureServices(ServiceConfigurationContext context)
public override void ConfigureServices(ServiceConfigurationContext context)
{
+ // Show neutral/versionless APIs.
+ context.Services.AddTransient();
context.Services.AddAbpApiVersioning(options =>
{
- // Show neutral/versionless APIs.
- options.UseApiBehavior = false;
-
options.ReportApiVersions = true;
options.AssumeDefaultVersionWhenUnspecified = true;
+ }).AddApiExplorer(options => {
+ // add the versioned api explorer, which also adds IApiVersionDescriptionProvider service
+ // note: the specified format code will format the version as "'v'major[.minor][-status]"
+ options.GroupNameFormat = "'v'VVV";
+
+ // note: this option is only necessary when versioning by url segment. the SubstitutionFormat
+ // can also be used to control the format of the API version in route templates
+ options.SubstituteApiVersionInUrl = true;
});
- context.Services.AddVersionedApiExplorer(
- options =>
- {
- // add the versioned api explorer, which also adds IApiVersionDescriptionProvider service
- // note: the specified format code will format the version as "'v'major[.minor][-status]"
- options.GroupNameFormat = "'v'VVV";
-
- // note: this option is only necessary when versioning by url segment. the SubstitutionFormat
- // can also be used to control the format of the API version in route templates
- options.SubstituteApiVersionInUrl = true;
- });
-
context.Services.AddTransient, ConfigureSwaggerOptions>();
context.Services.AddAbpSwaggerGen(
@@ -321,7 +314,7 @@ public override void OnApplicationInitialization(ApplicationInitializationContex
app.UseAbpRequestLocalization();
app.UseSwagger();
- app.UseSwaggerUI(
+ app.UseAbpSwaggerUI(
options =>
{
var provider = app.ApplicationServices.GetRequiredService();
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/Extensions/DependencyInjection/AbpApiVersioningExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/Extensions/DependencyInjection/AbpApiVersioningExtensions.cs
index c3f93fc06c..ac841bb5f8 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/Extensions/DependencyInjection/AbpApiVersioningExtensions.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/Extensions/DependencyInjection/AbpApiVersioningExtensions.cs
@@ -11,7 +11,7 @@ namespace Microsoft.Extensions.DependencyInjection;
public static class AbpApiVersioningExtensions
{
- public static IServiceCollection AddAbpApiVersioning(
+ public static IApiVersioningBuilder AddAbpApiVersioning(
this IServiceCollection services,
Action? apiVersioningOptionsSetupAction = null,
Action? mvcApiVersioningOptionsSetupAction = null)
@@ -21,9 +21,7 @@ public static class AbpApiVersioningExtensions
apiVersioningOptionsSetupAction ??= _ => { };
mvcApiVersioningOptionsSetupAction ??= _ => { };
- services.AddApiVersioning(apiVersioningOptionsSetupAction).AddMvc(mvcApiVersioningOptionsSetupAction);
-
- return services;
+ return services.AddApiVersioning(apiVersioningOptionsSetupAction).AddMvc(mvcApiVersioningOptionsSetupAction);
}
public static void ConfigureAbp(this MvcApiVersioningOptions options, AbpAspNetCoreMvcOptions mvcOptions)
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj
index c52ec08b2a..a6e2edc2cf 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj
@@ -32,6 +32,7 @@
+
diff --git a/npm/ng-packs/packages/schematics/src/commands/api/index.ts b/npm/ng-packs/packages/schematics/src/commands/api/index.ts
index 5f064e8f3f..c04ca1d433 100644
--- a/npm/ng-packs/packages/schematics/src/commands/api/index.ts
+++ b/npm/ng-packs/packages/schematics/src/commands/api/index.ts
@@ -48,21 +48,28 @@ export default function (schema: GenerateProxySchema) {
const createProxyConfigWriter = createProxyConfigWriterCreator(targetPath);
const data = readProxyConfig(tree);
data.types = sanitizeTypeNames(data.types);
+
const types = data.types;
const modules = data.modules;
const serviceType = schema.serviceType || defaultEServiceType;
- if (!types || !modules) throw new SchematicsException(Exception.InvalidApiDefinition);
+
+ if (!types || !modules) {
+ throw new SchematicsException(Exception.InvalidApiDefinition);
+ }
const definition = data.modules[moduleName];
- if (!definition)
+ if (!definition) {
throw new SchematicsException(interpolate(Exception.InvalidModule, moduleName));
+ }
const apiName = definition.remoteServiceName;
data.modules[moduleName].controllers = sanitizeControllerTypeNames(definition.controllers);
+
const controllers = filterControllersByServiceType(
serviceType,
data.modules[moduleName].controllers,
);
+
const serviceImports: Record = {};
const generateServices = createServiceGenerator({
targetPath,
@@ -90,8 +97,12 @@ export default function (schema: GenerateProxySchema) {
modelImports,
});
- if (!data.generated.includes(moduleName)) data.generated.push(moduleName);
+ if (!data.generated.includes(moduleName)) {
+ data.generated.push(moduleName);
+ }
+
data.generated.sort();
+
const json = generateProxyConfigJson(data);
const overwriteProxyConfig = createProxyConfigWriter('overwrite', json);
@@ -129,11 +140,18 @@ function createModelGenerator(params: ModelGeneratorParams) {
const { targetPath, serviceImports, modelImports } = params;
const reduceImportRefsToModels = createImportRefsToModelReducer(params);
const models = Object.values(serviceImports).reduce(reduceImportRefsToModels, []);
+
models.forEach(({ imports }) =>
imports.forEach(({ refs, path }) =>
refs.forEach(ref => {
- if (path === '@abp/ng.core') return;
- if (!modelImports[path]) return (modelImports[path] = [ref]);
+ if (path === '@abp/ng.core') {
+ return;
+ }
+
+ if (!modelImports[path]) {
+ return (modelImports[path] = [ref]);
+ }
+
modelImports[path] = [...new Set([...modelImports[path], ref])];
}),
),
diff --git a/npm/ng-packs/packages/schematics/src/utils/model.ts b/npm/ng-packs/packages/schematics/src/utils/model.ts
index 11ff88d15a..52b9b36be0 100644
--- a/npm/ng-packs/packages/schematics/src/utils/model.ts
+++ b/npm/ng-packs/packages/schematics/src/utils/model.ts
@@ -71,23 +71,30 @@ export function createImportRefsToModelReducer(params: ModelGeneratorParams) {
model.interfaces.forEach(_interface => {
const { baseType } = types[_interface.ref];
- if (baseType && parseNamespace(solution, baseType) !== model.namespace){
+ if (baseType && parseNamespace(solution, baseType) !== model.namespace) {
const baseTypeWithGenericParams = parseBaseTypeWithGenericTypes(baseType);
baseTypeWithGenericParams.forEach(t => {
toBeImported.push({
type: t,
isEnum: false,
});
- })
+ });
+ }
-}
[..._interface.properties, ..._interface.generics].forEach(prop => {
prop.refs.forEach(ref => {
const propType = types[ref];
- if (!propType) return;
- if (propType.isEnum) toBeImported.push({ type: ref, isEnum: true });
- else if (parseNamespace(solution, ref) !== model.namespace)
+ if (!propType) {
+ return;
+ }
+
+ if (propType.isEnum) {
+ toBeImported.push({ type: ref, isEnum: true });
+ }
+
+ if (parseNamespace(solution, ref) !== model.namespace) {
toBeImported.push({ type: ref, isEnum: false });
+ }
});
});
});
@@ -176,20 +183,21 @@ export function createRefToImportReducerCreator(params: ModelGeneratorParams) {
}
function isOptionalProperty(prop: PropertyDef) {
- return (prop.typeSimple.endsWith('?') || (prop.typeSimple === 'string' && !prop.isRequired));
+ return prop.typeSimple.endsWith('?') || (prop.typeSimple === 'string' && !prop.isRequired);
}
-export function parseBaseTypeWithGenericTypes(type: string): string[] {
+export function parseBaseTypeWithGenericTypes(type: string): string[] {
const parsedTypeNode = parseGenerics(type);
- const nodeToText = (node: TypeNode,acc:string[] = []): string[] => {
+ const nodeToText = (node: TypeNode, acc: string[] = []): string[] => {
acc.push(node.data);
- if(node.children && node.children.length > 0){
+ if (node.children && node.children.length > 0) {
node.children.forEach(child => {
- nodeToText(child,acc);
- })
+ nodeToText(child, acc);
+ });
}
return acc;
- }
+ };
+
return nodeToText(parsedTypeNode);
}
diff --git a/npm/ng-packs/packages/schematics/src/utils/type.ts b/npm/ng-packs/packages/schematics/src/utils/type.ts
index a5c83f8e63..63c69c7aec 100644
--- a/npm/ng-packs/packages/schematics/src/utils/type.ts
+++ b/npm/ng-packs/packages/schematics/src/utils/type.ts
@@ -14,7 +14,7 @@ export function createTypeSimplifier() {
);
type = /any${array}` : identifier;
});
@@ -64,12 +64,21 @@ export function createTypesToImportsReducer(solution: string, namespace: string)
return (imports: Import[], types: TypeWithEnum[]) => {
types.forEach(({ type, isEnum }) => {
const newImport = mapTypeToImport(type, isEnum);
- if (!newImport) return;
+ if (!newImport) {
+ return;
+ }
+
+ if(newImport.specifiers.some(f => f.toLocaleLowerCase() === type.toLocaleLowerCase())){
+ return;
+ }
const existingImport = imports.find(
({ keyword, path }) => keyword === newImport.keyword && path === newImport.path,
);
- if (!existingImport) return imports.push(newImport);
+
+ if (!existingImport){
+ return imports.push(newImport);
+ }
existingImport.refs = [...new Set([...existingImport.refs, ...newImport.refs])];
existingImport.specifiers = [
@@ -91,11 +100,15 @@ export function createTypeToImportMapper(solution: string, namespace: string) {
const modelNamespace = parseNamespace(solution, type);
const refs = [removeTypeModifiers(type)];
const specifiers = [adaptType(simplifyType(refs[0]).split('<')[0])];
- const path = VOLO_REGEX.test(type)
- ? '@abp/ng.core'
- : isEnum
- ? relativePathToEnum(namespace, modelNamespace, specifiers[0])
- : relativePathToModel(namespace, modelNamespace);
+ let path = relativePathToModel(namespace, modelNamespace);
+
+ if (VOLO_REGEX.test(type)) {
+ path = '@abp/ng.core';
+ }
+
+ if (isEnum) {
+ path = relativePathToEnum(namespace, modelNamespace, specifiers[0]);
+ }
return new Import({ keyword: eImportKeyword.Type, path, refs, specifiers });
};