From 1263af81f0fbf170753735c250e81d0af96c2ed8 Mon Sep 17 00:00:00 2001 From: David Kallesen Date: Mon, 13 Jan 2025 19:31:25 +0100 Subject: [PATCH 01/11] feat: add ContractsNamespace, EndpointsNamespace, HandlersNamespace cli-parameters to GeneratorSettings --- .../ApiOptionsHelper.cs | 42 ++++++++++++++++--- .../Commands/ArgumentCommandConstants.cs | 3 ++ .../Settings/BaseGenerateCommandSettings.cs | 12 ++++++ .../Settings/GeneratorSettings.cs | 6 +++ .../Factories/GeneratorSettingsFactory.cs | 15 +++++++ .../Options/ApiOptionsGenerator.cs | 6 +++ 6 files changed, 78 insertions(+), 6 deletions(-) diff --git a/src/Atc.Rest.ApiGenerator.CLI/ApiOptionsHelper.cs b/src/Atc.Rest.ApiGenerator.CLI/ApiOptionsHelper.cs index d9d09ac63..f441f92ea 100644 --- a/src/Atc.Rest.ApiGenerator.CLI/ApiOptionsHelper.cs +++ b/src/Atc.Rest.ApiGenerator.CLI/ApiOptionsHelper.cs @@ -154,16 +154,28 @@ private static void ApplyGeneratorOverrides( apiOptions.Generator.ProjectName = serverCommandSettings.ProjectPrefixName; } + if (serverCommandSettings.EndpointsLocation is not null && + serverCommandSettings.EndpointsLocation.IsSet) + { + apiOptions.Generator.EndpointsLocation = serverCommandSettings.EndpointsLocation.Value; + } + + if (serverCommandSettings.EndpointsNamespace is not null && + serverCommandSettings.EndpointsNamespace.IsSet) + { + apiOptions.Generator.EndpointsNamespace = serverCommandSettings.EndpointsNamespace.Value; + } + if (serverCommandSettings.ContractsLocation is not null && serverCommandSettings.ContractsLocation.IsSet) { apiOptions.Generator.ContractsLocation = serverCommandSettings.ContractsLocation.Value; } - if (serverCommandSettings.EndpointsLocation is not null && - serverCommandSettings.EndpointsLocation.IsSet) + if (serverCommandSettings.ContractsNamespace is not null && + serverCommandSettings.ContractsNamespace.IsSet) { - apiOptions.Generator.EndpointsLocation = serverCommandSettings.EndpointsLocation.Value; + apiOptions.Generator.ContractsNamespace = serverCommandSettings.ContractsNamespace.Value; } if (serverCommandSettings.HandlersLocation is not null && @@ -172,6 +184,12 @@ private static void ApplyGeneratorOverrides( apiOptions.Generator.HandlersLocation = serverCommandSettings.HandlersLocation.Value; } + if (serverCommandSettings.HandlersNamespace is not null && + serverCommandSettings.HandlersNamespace.IsSet) + { + apiOptions.Generator.HandlersNamespace = serverCommandSettings.HandlersNamespace.Value; + } + if (serverCommandSettings.UsePartialClassForContracts) { apiOptions.Generator.UsePartialClassForContracts = serverCommandSettings.UsePartialClassForContracts; @@ -212,16 +230,28 @@ private static void ApplyGeneratorOverrides( apiOptions.Generator.ProjectSuffixName = $"{ContentGeneratorConstants.DefaultHttpClientName}.Generated"; } + if (clientApiCommandSettings.EndpointsLocation is not null && + clientApiCommandSettings.EndpointsLocation.IsSet) + { + apiOptions.Generator.EndpointsLocation = clientApiCommandSettings.EndpointsLocation.Value; + } + + if (clientApiCommandSettings.EndpointsNamespace is not null && + clientApiCommandSettings.EndpointsNamespace.IsSet) + { + apiOptions.Generator.EndpointsNamespace = clientApiCommandSettings.EndpointsNamespace.Value; + } + if (clientApiCommandSettings.ContractsLocation is not null && clientApiCommandSettings.ContractsLocation.IsSet) { apiOptions.Generator.ContractsLocation = clientApiCommandSettings.ContractsLocation.Value; } - if (clientApiCommandSettings.EndpointsLocation is not null && - clientApiCommandSettings.EndpointsLocation.IsSet) + if (clientApiCommandSettings.ContractsNamespace is not null && + clientApiCommandSettings.ContractsNamespace.IsSet) { - apiOptions.Generator.EndpointsLocation = clientApiCommandSettings.EndpointsLocation.Value; + apiOptions.Generator.ContractsNamespace = clientApiCommandSettings.ContractsNamespace.Value; } if (clientApiCommandSettings.UsePartialClassForContracts) diff --git a/src/Atc.Rest.ApiGenerator.CLI/Commands/ArgumentCommandConstants.cs b/src/Atc.Rest.ApiGenerator.CLI/Commands/ArgumentCommandConstants.cs index cb385698f..ba492c320 100644 --- a/src/Atc.Rest.ApiGenerator.CLI/Commands/ArgumentCommandConstants.cs +++ b/src/Atc.Rest.ApiGenerator.CLI/Commands/ArgumentCommandConstants.cs @@ -21,8 +21,11 @@ public static class ArgumentCommandConstants public const string LongConfigurationValidateModelPropertyNameCasingStyle = "--validate-modelPropertyNameCasingStyle"; public const string LongEndpointsLocation = "--endpointsLocation"; + public const string LongEndpointsNamespace = "--endpointsNamespace"; public const string LongContractsLocation = "--contractsLocation"; + public const string LongContractsNamespace = "--contractsNamespace"; public const string LongHandlersLocation = "--handlersLocation"; + public const string LongHandlersNamespace = "--handlersNamespace"; public const string LongClientHttpClientName = "--httpClientName"; public const string LongExcludeEndpointGeneration = "--excludeEndpointGeneration"; diff --git a/src/Atc.Rest.ApiGenerator.CLI/Commands/Settings/BaseGenerateCommandSettings.cs b/src/Atc.Rest.ApiGenerator.CLI/Commands/Settings/BaseGenerateCommandSettings.cs index 1234d1990..c1892a948 100644 --- a/src/Atc.Rest.ApiGenerator.CLI/Commands/Settings/BaseGenerateCommandSettings.cs +++ b/src/Atc.Rest.ApiGenerator.CLI/Commands/Settings/BaseGenerateCommandSettings.cs @@ -18,14 +18,26 @@ public class BaseGenerateCommandSettings : BaseConfigurationCommandSettings [Description($"If endpoints-localtion is provided, generated files will be placed here instead of the {ContentGeneratorConstants.Endpoints} folder.")] public FlagValue? EndpointsLocation { get; init; } + [CommandOption($"{ArgumentCommandConstants.LongEndpointsNamespace} [ENDPOINTSNAMESPACE]")] + [Description($"If endpoints-namespace is provided, generated files will be placed here instead of the {ContentGeneratorConstants.Endpoints} namespace.")] + public FlagValue? EndpointsNamespace { get; init; } + [CommandOption($"{ArgumentCommandConstants.LongContractsLocation} [CONTRACTSLOCATION]")] [Description($"If contracts-localtion is provided, generated files will be placed here instead of the {ContentGeneratorConstants.Contracts} folder.")] public FlagValue? ContractsLocation { get; init; } + [CommandOption($"{ArgumentCommandConstants.LongContractsNamespace} [CONTRACTSNAMESPACE]")] + [Description($"If contracts-namespace is provided, generated files will be placed here instead of the {ContentGeneratorConstants.Contracts} namespace.")] + public FlagValue? ContractsNamespace { get; init; } + [CommandOption($"{ArgumentCommandConstants.LongHandlersLocation} [HANDLERSLOCATION]")] [Description($"If handlers-localtion is provided, generated files will be placed here instead of the {ContentGeneratorConstants.Handlers} folder.")] public FlagValue? HandlersLocation { get; init; } + [CommandOption($"{ArgumentCommandConstants.LongHandlersNamespace} [HANDLERSNAMESPACE]")] + [Description($"If handlers-namespace is provided, generated files will be placed here instead of the {ContentGeneratorConstants.Handlers} namespace.")] + public FlagValue? HandlersNamespace { get; init; } + [CommandOption(ArgumentCommandConstants.LongUsePartialClassForContracts)] [Description("Use Partial-Class for contracts")] public bool UsePartialClassForContracts { get; init; } diff --git a/src/Atc.Rest.ApiGenerator.Framework/Settings/GeneratorSettings.cs b/src/Atc.Rest.ApiGenerator.Framework/Settings/GeneratorSettings.cs index b71b4f525..b3a026771 100644 --- a/src/Atc.Rest.ApiGenerator.Framework/Settings/GeneratorSettings.cs +++ b/src/Atc.Rest.ApiGenerator.Framework/Settings/GeneratorSettings.cs @@ -13,10 +13,16 @@ public class GeneratorSettings( public string EndpointsLocation { get; set; } = ContentGeneratorConstants.Endpoints; + public string EndpointsNamespace { get; set; } = ContentGeneratorConstants.Endpoints; + public string ContractsLocation { get; set; } = ContentGeneratorConstants.Contracts; + public string ContractsNamespace { get; set; } = ContentGeneratorConstants.Contracts; + public string HandlersLocation { get; set; } = ContentGeneratorConstants.Handlers; + public string HandlersNamespace { get; set; } = ContentGeneratorConstants.Handlers; + public bool UsePartialClassForContracts { get; set; } public bool UsePartialClassForEndpoints { get; set; } diff --git a/src/Atc.Rest.ApiGenerator/Factories/GeneratorSettingsFactory.cs b/src/Atc.Rest.ApiGenerator/Factories/GeneratorSettingsFactory.cs index eb2fee70b..1227de821 100644 --- a/src/Atc.Rest.ApiGenerator/Factories/GeneratorSettingsFactory.cs +++ b/src/Atc.Rest.ApiGenerator/Factories/GeneratorSettingsFactory.cs @@ -27,16 +27,31 @@ public static GeneratorSettings Create( generatorSettings.EndpointsLocation = apiOptionsGenerator.EndpointsLocation; } + if (!string.IsNullOrEmpty(apiOptionsGenerator.EndpointsNamespace)) + { + generatorSettings.EndpointsNamespace = apiOptionsGenerator.EndpointsNamespace; + } + if (!string.IsNullOrEmpty(apiOptionsGenerator.ContractsLocation)) { generatorSettings.ContractsLocation = apiOptionsGenerator.ContractsLocation; } + if (!string.IsNullOrEmpty(apiOptionsGenerator.ContractsNamespace)) + { + generatorSettings.ContractsNamespace = apiOptionsGenerator.ContractsNamespace; + } + if (!string.IsNullOrEmpty(apiOptionsGenerator.HandlersLocation)) { generatorSettings.HandlersLocation = apiOptionsGenerator.HandlersLocation; } + if (!string.IsNullOrEmpty(apiOptionsGenerator.HandlersNamespace)) + { + generatorSettings.HandlersNamespace = apiOptionsGenerator.HandlersNamespace; + } + return generatorSettings; } } \ No newline at end of file diff --git a/src/Atc.Rest.ApiGenerator/Options/ApiOptionsGenerator.cs b/src/Atc.Rest.ApiGenerator/Options/ApiOptionsGenerator.cs index 94db2e280..72b05c0a3 100644 --- a/src/Atc.Rest.ApiGenerator/Options/ApiOptionsGenerator.cs +++ b/src/Atc.Rest.ApiGenerator/Options/ApiOptionsGenerator.cs @@ -14,10 +14,16 @@ public class ApiOptionsGenerator public string ContractsLocation { get; set; } = ContentGeneratorConstants.Contracts + ".[[apiGroupName]]"; + public string ContractsNamespace { get; set; } = ContentGeneratorConstants.Contracts + ".[[apiGroupName]]"; + public string EndpointsLocation { get; set; } = ContentGeneratorConstants.Endpoints + ".[[apiGroupName]]"; + public string EndpointsNamespace { get; set; } = ContentGeneratorConstants.Endpoints + ".[[apiGroupName]]"; + public string HandlersLocation { get; set; } = ContentGeneratorConstants.Handlers + ".[[apiGroupName]]"; + public string HandlersNamespace { get; set; } = ContentGeneratorConstants.Handlers + ".[[apiGroupName]]"; + public bool UsePartialClassForContracts { get; set; } public bool UsePartialClassForEndpoints { get; set; } From 3057e1e74dc5e49a7d0bcdbd7752814bcfa0a47c Mon Sep 17 00:00:00 2001 From: David Kallesen Date: Mon, 13 Jan 2025 19:32:22 +0100 Subject: [PATCH 02/11] feat: update nuget Atc.Rest.Client to 1.0.84 --- .../Providers/NugetPackageReferenceProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Atc.Rest.ApiGenerator.Framework/Providers/NugetPackageReferenceProvider.cs b/src/Atc.Rest.ApiGenerator.Framework/Providers/NugetPackageReferenceProvider.cs index 511c7dbf1..764e22dc9 100644 --- a/src/Atc.Rest.ApiGenerator.Framework/Providers/NugetPackageReferenceProvider.cs +++ b/src/Atc.Rest.ApiGenerator.Framework/Providers/NugetPackageReferenceProvider.cs @@ -11,7 +11,7 @@ public class NugetPackageReferenceProvider( { "Atc", "2.0.525" }, { "Atc.Azure.Options", "3.0.31" }, { "Atc.Rest", "2.0.525" }, - { "Atc.Rest.Client", "1.0.36" }, + { "Atc.Rest.Client", "1.0.84" }, { "Atc.Rest.Extended", "2.0.525" }, { "Atc.Rest.FluentAssertions", "2.0.525" }, { "Atc.Rest.MinimalApi", "1.0.87" }, From 1a9c10568202d46a973481ce82f1c8ad25255c09 Mon Sep 17 00:00:00 2001 From: David Kallesen Date: Mon, 13 Jan 2025 19:33:27 +0100 Subject: [PATCH 03/11] feat: use settings.[X]Namespace for ClientCSharpApiGenerator --- .../ClientCSharpApiGenerator.cs | 74 ++++++++++++------- .../Factories/NamespaceFactory.cs | 9 +++ ...eneratorClientEndpointParametersFactory.cs | 4 +- ...ndpointResultInterfaceParametersFactory.cs | 4 +- ...orClientEndpointResultParametersFactory.cs | 4 +- 5 files changed, 61 insertions(+), 34 deletions(-) diff --git a/src/Atc.Rest.ApiGenerator.Client.CSharp/ProjectGenerator/ClientCSharpApiGenerator.cs b/src/Atc.Rest.ApiGenerator.Client.CSharp/ProjectGenerator/ClientCSharpApiGenerator.cs index 91c45ca92..278943078 100644 --- a/src/Atc.Rest.ApiGenerator.Client.CSharp/ProjectGenerator/ClientCSharpApiGenerator.cs +++ b/src/Atc.Rest.ApiGenerator.Client.CSharp/ProjectGenerator/ClientCSharpApiGenerator.cs @@ -128,9 +128,11 @@ public void GenerateParameters() { var apiGroupName = openApiPath.GetApiGroupName(); - var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsNamespace); + + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsLocation); + var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); foreach (var openApiOperation in openApiPath.Value.Operations) { @@ -174,9 +176,11 @@ public void GenerateEndpointInterfaces() { var apiGroupName = openApiPath.GetApiGroupName(); - var endpointsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.EndpointsLocation); + var endpointsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.EndpointsNamespace); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, endpointsLocation) + $".{ContentGeneratorConstants.Interfaces}"; + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, endpointsNamespace) + $".{ContentGeneratorConstants.Interfaces}"; + + var endpointsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.EndpointsLocation); foreach (var openApiOperation in openApiPath.Value.Operations) { @@ -216,10 +220,12 @@ public void GenerateEndpoints() { var apiGroupName = openApiPath.GetApiGroupName(); - var endpointsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.EndpointsLocation); - var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var endpointsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.EndpointsNamespace); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, endpointsLocation); + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, endpointsNamespace); + + var endpointsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.EndpointsLocation); + var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsNamespace); foreach (var openApiOperation in openApiPath.Value.Operations) { @@ -232,7 +238,7 @@ public void GenerateEndpoints() settings.ProjectName, apiGroupName, fullNamespace, - contractsLocation, + contractsNamespace, openApiPath.Value, openApiOperation.Key, openApiOperation.Value, @@ -266,10 +272,12 @@ public void GenerateEndpointResultInterfaces() { var apiGroupName = openApiPath.GetApiGroupName(); - var endpointsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.EndpointsLocation); - var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var endpointsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.EndpointsNamespace); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, endpointsLocation) + $".{ContentGeneratorConstants.Interfaces}"; + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, endpointsNamespace) + $".{ContentGeneratorConstants.Interfaces}"; + + var endpointsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.EndpointsLocation); + var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsNamespace); foreach (var openApiOperation in openApiPath.Value.Operations) { @@ -282,7 +290,7 @@ public void GenerateEndpointResultInterfaces() settings.ProjectName, apiGroupName, fullNamespace, - contractsLocation, + contractsNamespace, openApiPath.Value, openApiOperation.Value, settings.UsePartialClassForContracts); @@ -312,10 +320,12 @@ public void GenerateEndpointResults() { var apiGroupName = openApiPath.GetApiGroupName(); - var endpointsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.EndpointsLocation); - var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var endpointsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.EndpointsNamespace); + + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, endpointsNamespace); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, endpointsLocation); + var endpointsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.EndpointsLocation); + var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsNamespace); foreach (var openApiOperation in openApiPath.Value.Operations) { @@ -328,7 +338,7 @@ public void GenerateEndpointResults() settings.ProjectName, apiGroupName, fullNamespace, - contractsLocation, + contractsNamespace, openApiPath.Value, openApiOperation.Value, settings.UsePartialClassForContracts); @@ -397,7 +407,7 @@ public void MaintainGlobalUsings( if (operationSchemaMappings.Any(apiOperation => apiOperation.Model.IsShared)) { - requiredUsings.Add(NamespaceFactory.Create(settings.ProjectName, LocationFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation))); + requiredUsings.Add(NamespaceFactory.Create(settings.ProjectName, NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsNamespace))); } var apiGroupNames = openApiDocument.GetApiGroupNames(); @@ -405,7 +415,7 @@ public void MaintainGlobalUsings( { var apiGroupName = openApiPath.GetApiGroupName(); - var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsNamespace); foreach (var openApiOperation in openApiPath.Value.Operations) { @@ -420,7 +430,7 @@ public void MaintainGlobalUsings( continue; } - var requiredUsing = NamespaceFactory.Create(settings.ProjectName, contractsLocation); + var requiredUsing = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); if (!requiredUsings.Contains(requiredUsing, StringComparer.CurrentCulture)) { requiredUsings.Add(requiredUsing); @@ -436,7 +446,7 @@ public void MaintainGlobalUsings( var apiOperationModels = GetDistinctApiOperationModels(apiOperations); - var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsNamespace); foreach (var apiOperationModel in apiOperationModels) { @@ -451,7 +461,7 @@ public void MaintainGlobalUsings( continue; } - var requiredUsing = NamespaceFactory.Create(settings.ProjectName, contractsLocation); + var requiredUsing = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); if (!requiredUsings.Contains(requiredUsing, StringComparer.CurrentCulture)) { requiredUsings.Add(requiredUsing); @@ -459,7 +469,7 @@ public void MaintainGlobalUsings( } } - requiredUsings.AddRange(apiGroupNames.Select(x => NamespaceFactory.Create(settings.ProjectName, LocationFactory.CreateWithApiGroupName(x, settings.EndpointsLocation), ContentGeneratorConstants.Interfaces))); + requiredUsings.AddRange(apiGroupNames.Select(x => NamespaceFactory.Create(settings.ProjectName, NamespaceFactory.CreateWithApiGroupName(x, settings.EndpointsNamespace), ContentGeneratorConstants.Interfaces))); GlobalUsingsHelper.CreateOrUpdate( logger, @@ -473,9 +483,11 @@ private void GenerateEnumerationType( string enumerationName, OpenApiSchema openApiSchemaEnumeration) { - var contractsLocation = LocationFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation); + var contractsNamespace = NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsNamespace); + + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsLocation); + var contractsLocation = LocationFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation); var enumParameters = ContentGeneratorServerClientEnumParametersFactory.Create( codeGeneratorContentHeader, @@ -504,12 +516,16 @@ private void GenerateModel( string apiGroupName, bool isSharedContract) { + var contractsNamespace = isSharedContract + ? NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsNamespace) + : NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsNamespace); + + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); + var contractsLocation = isSharedContract ? LocationFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation) : LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsLocation); - var parameters = ContentGeneratorServerClientModelParametersFactory.CreateForClass( codeGeneratorContentHeader, fullNamespace, @@ -543,9 +559,11 @@ private void GenerateCustomErrorResponseModel() return; } - var contractsLocation = LocationFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation); + var contractsNamespace = NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsNamespace); + + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsLocation); + var contractsLocation = LocationFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation); var parameters = ContentGeneratorServerClientModelParametersFactory.CreateForCustomErrorResponseModel( codeGeneratorContentHeader, diff --git a/src/Atc.Rest.ApiGenerator.Framework/Factories/NamespaceFactory.cs b/src/Atc.Rest.ApiGenerator.Framework/Factories/NamespaceFactory.cs index da0e302fd..f12b9b922 100644 --- a/src/Atc.Rest.ApiGenerator.Framework/Factories/NamespaceFactory.cs +++ b/src/Atc.Rest.ApiGenerator.Framework/Factories/NamespaceFactory.cs @@ -21,4 +21,13 @@ public static string Create( return fullNamespace; } + + public static string CreateWithApiGroupName( + string apiGroupName, + string value) + => LocationFactory.CreateWithApiGroupName(apiGroupName, value); + + public static string CreateWithoutTemplateForApiGroupName( + string value) + => LocationFactory.CreateWithoutTemplateForApiGroupName(value); } \ No newline at end of file diff --git a/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Client/ContentGeneratorClientEndpointParametersFactory.cs b/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Client/ContentGeneratorClientEndpointParametersFactory.cs index 9573dbf70..f56b3584c 100644 --- a/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Client/ContentGeneratorClientEndpointParametersFactory.cs +++ b/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Client/ContentGeneratorClientEndpointParametersFactory.cs @@ -6,7 +6,7 @@ public static ContentGeneratorClientEndpointParameters Create( string projectName, string apiGroupName, string @namespace, - string contractsLocation, + string contractsNamespace, OpenApiPathItem openApiPath, OperationType httpMethod, OpenApiOperation openApiOperation, @@ -23,7 +23,7 @@ public static ContentGeneratorClientEndpointParameters Create( AppendParameters(parameters, openApiOperation.Parameters); AppendParametersFromBody(parameters, openApiOperation.RequestBody); - var modelNamespace = NamespaceFactory.Create(projectName, contractsLocation); + var modelNamespace = NamespaceFactory.Create(projectName, contractsNamespace); var operationName = openApiOperation.GetOperationName(); var controllerAuthorization = openApiPath.ExtractApiPathAuthorization(); var endpointAuthorization = openApiOperation.ExtractApiOperationAuthorization(openApiPath); diff --git a/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Client/ContentGeneratorClientEndpointResultInterfaceParametersFactory.cs b/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Client/ContentGeneratorClientEndpointResultInterfaceParametersFactory.cs index 5d55ad825..e97862e66 100644 --- a/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Client/ContentGeneratorClientEndpointResultInterfaceParametersFactory.cs +++ b/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Client/ContentGeneratorClientEndpointResultInterfaceParametersFactory.cs @@ -6,7 +6,7 @@ public static ContentGeneratorClientEndpointResultInterfaceParameters Create( string projectName, string apiGroupName, string @namespace, - string contractsLocation, + string contractsNamespace, OpenApiPathItem openApiPath, OpenApiOperation openApiOperation, bool usePartialClass) @@ -20,7 +20,7 @@ public static ContentGeneratorClientEndpointResultInterfaceParameters Create( AppendParameters(parameters, openApiOperation.Parameters); AppendParametersFromBody(parameters, openApiOperation.RequestBody); - var modelNamespace = NamespaceFactory.Create(projectName, contractsLocation); + var modelNamespace = NamespaceFactory.Create(projectName, contractsNamespace); var operationName = openApiOperation.GetOperationName(); var controllerAuthorization = openApiPath.ExtractApiPathAuthorization(); var endpointAuthorization = openApiOperation.ExtractApiOperationAuthorization(openApiPath); diff --git a/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Client/ContentGeneratorClientEndpointResultParametersFactory.cs b/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Client/ContentGeneratorClientEndpointResultParametersFactory.cs index 3d58d197a..8a591f569 100644 --- a/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Client/ContentGeneratorClientEndpointResultParametersFactory.cs +++ b/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Client/ContentGeneratorClientEndpointResultParametersFactory.cs @@ -6,7 +6,7 @@ public static ContentGeneratorClientEndpointResultParameters Create( string projectName, string apiGroupName, string @namespace, - string contractsLocation, + string contractsNamespace, OpenApiPathItem openApiPath, OpenApiOperation openApiOperation, bool usePartialClass) @@ -20,7 +20,7 @@ public static ContentGeneratorClientEndpointResultParameters Create( AppendParameters(parameters, openApiOperation.Parameters); AppendParametersFromBody(parameters, openApiOperation.RequestBody); - var modelNamespace = NamespaceFactory.Create(projectName, contractsLocation); + var modelNamespace = NamespaceFactory.Create(projectName, contractsNamespace); var operationName = openApiOperation.GetOperationName(); var controllerAuthorization = openApiPath.ExtractApiPathAuthorization(); var endpointAuthorization = openApiOperation.ExtractApiOperationAuthorization(openApiPath); From 40cb2693ad39a05ebefc5db292abc65b532dc7fa Mon Sep 17 00:00:00 2001 From: David Kallesen Date: Mon, 13 Jan 2025 20:15:18 +0100 Subject: [PATCH 04/11] feat: use settings.[X]Namespace for Server[X]Generator --- .../ProjectGenerator/ServerApiGenerator.cs | 48 +++++++++++++------ .../ProjectGenerator/ServerDomainGenerator.cs | 2 +- .../ServerHostTestGenerator.cs | 4 +- .../ProjectGenerator/ServerApiGenerator.cs | 48 +++++++++++++------ .../ProjectGenerator/ServerDomainGenerator.cs | 2 +- .../ServerHostTestGenerator.cs | 4 +- .../Extensions/OpenApiPathItemExtensions.cs | 25 ++++++++++ 7 files changed, 97 insertions(+), 36 deletions(-) diff --git a/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerApiGenerator.cs b/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerApiGenerator.cs index a5a3f94bf..95a4b2814 100644 --- a/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerApiGenerator.cs +++ b/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerApiGenerator.cs @@ -150,9 +150,11 @@ public void GenerateParameters() { var apiGroupName = openApiPath.GetApiGroupName(); - var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsNamespace); + + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsLocation); + var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); foreach (var openApiOperation in openApiPath.Value.Operations) { @@ -196,9 +198,11 @@ public void GenerateResults() { var apiGroupName = openApiPath.GetApiGroupName(); - var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsLocation); + var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); foreach (var openApiOperation in openApiPath.Value.Operations) { @@ -236,9 +240,11 @@ public void GenerateInterfaces() { var apiGroupName = openApiPath.GetApiGroupName(); - var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsLocation); + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); + + var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); foreach (var openApiOperation in openApiPath.Value.Operations) { @@ -274,9 +280,11 @@ public void GenerateEndpoints() { foreach (var apiGroupName in openApiDocument.GetApiGroupNames()) { - var endpointsLocation = LocationFactory.CreateWithoutTemplateForApiGroupName(settings.EndpointsLocation); + var endpointsNamespace = NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.EndpointsNamespace); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, endpointsLocation); + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, endpointsNamespace); + + var endpointsLocation = LocationFactory.CreateWithoutTemplateForApiGroupName(settings.EndpointsLocation); var endpointParameters = ContentGeneratorServerEndpointParametersFactory.Create( operationSchemaMappings, @@ -352,7 +360,7 @@ public void MaintainGlobalUsings( { var requiredUsing = NamespaceFactory.Create( settings.ProjectName, - LocationFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation)); + LocationFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsNamespace)); if (!requiredUsings.Contains(requiredUsing, StringComparer.CurrentCulture)) { @@ -362,7 +370,7 @@ public void MaintainGlobalUsings( var apiGroupNames = openApiDocument.GetApiGroupNames(); - requiredUsings.AddRange(apiGroupNames.Select(x => NamespaceFactory.Create(settings.ProjectName, LocationFactory.CreateWithApiGroupName(x, settings.ContractsLocation)))); + requiredUsings.AddRange(apiGroupNames.Select(x => NamespaceFactory.Create(settings.ProjectName, NamespaceFactory.CreateWithApiGroupName(x, settings.ContractsNamespace)))); GlobalUsingsHelper.CreateOrUpdate( logger, @@ -378,7 +386,11 @@ private string GetRouteByApiGroupName( var (key, _) = openApiDocument.Paths.FirstOrDefault(x => x.IsPathStartingSegmentName(apiGroupName)); if (key is null) { - throw new NotSupportedException($"{nameof(apiGroupName)} was not found in any route."); + (key, _) = openApiDocument.Paths.FirstOrDefault(x => x.IsPathStartingApiGroupName(apiGroupName)); + if (key is null) + { + throw new NotSupportedException($"{nameof(apiGroupName)} was not found in any route."); + } } var routeSuffix = key @@ -392,9 +404,11 @@ private void GenerateEnumerationType( string enumerationName, OpenApiSchema openApiSchemaEnumeration) { - var contractsLocation = LocationFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation); + var contractsNamespace = NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsNamespace); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsLocation); + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); + + var contractsLocation = LocationFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation); var enumParameters = ContentGeneratorServerClientEnumParametersFactory.Create( codeGeneratorContentHeader, @@ -423,12 +437,16 @@ private void GenerateModel( string apiGroupName, bool isSharedContract) { + var contractsNamespace = isSharedContract + ? NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsNamespace) + : NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsNamespace); + + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); + var contractsLocation = isSharedContract ? LocationFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation) : LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsLocation); - var parameters = ContentGeneratorServerClientModelParametersFactory.CreateForRecord( codeGeneratorContentHeader, fullNamespace, diff --git a/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerDomainGenerator.cs b/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerDomainGenerator.cs index 12030a56d..83135a392 100644 --- a/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerDomainGenerator.cs +++ b/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerDomainGenerator.cs @@ -257,7 +257,7 @@ public void MaintainGlobalUsings( var apiGroupNames = openApiDocument.GetApiGroupNames(); - requiredUsings.AddRange(apiGroupNames.Select(x => NamespaceFactory.Create(apiProjectName, LocationFactory.CreateWithApiGroupName(x, settings.ContractsLocation)))); + requiredUsings.AddRange(apiGroupNames.Select(x => NamespaceFactory.Create(apiProjectName, NamespaceFactory.CreateWithApiGroupName(x, settings.ContractsLocation)))); GlobalUsingsHelper.CreateOrUpdate( logger, diff --git a/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerHostTestGenerator.cs b/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerHostTestGenerator.cs index 8a3f277db..f2f3b292a 100644 --- a/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerHostTestGenerator.cs +++ b/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerHostTestGenerator.cs @@ -275,7 +275,7 @@ public void MaintainGlobalUsings( if (operationSchemaMappings.Any(apiOperation => apiOperation.Model.IsShared)) { - requiredUsings.Add(NamespaceFactory.Create(apiProjectName, LocationFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation))); + requiredUsings.Add(NamespaceFactory.Create(apiProjectName, NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation))); } var apiGroupNames = openApiDocument.GetApiGroupNames(); @@ -287,7 +287,7 @@ public void MaintainGlobalUsings( continue; } - requiredUsings.Add(NamespaceFactory.Create(apiProjectName, LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation))); + requiredUsings.Add(NamespaceFactory.Create(apiProjectName, NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation))); } GlobalUsingsHelper.CreateOrUpdate( diff --git a/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerApiGenerator.cs b/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerApiGenerator.cs index e0d6f125f..5ea73d626 100644 --- a/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerApiGenerator.cs +++ b/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerApiGenerator.cs @@ -166,9 +166,11 @@ public void GenerateParameters() { var apiGroupName = openApiPath.GetApiGroupName(); - var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsNamespace); + + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsLocation); + var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); foreach (var openApiOperation in openApiPath.Value.Operations) { @@ -212,9 +214,11 @@ public void GenerateResults() { var apiGroupName = openApiPath.GetApiGroupName(); - var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsLocation); + var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); foreach (var openApiOperation in openApiPath.Value.Operations) { @@ -252,9 +256,11 @@ public void GenerateInterfaces() { var apiGroupName = openApiPath.GetApiGroupName(); - var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsLocation); + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); + + var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); foreach (var openApiOperation in openApiPath.Value.Operations) { @@ -290,9 +296,11 @@ public void GenerateEndpoints() { foreach (var apiGroupName in openApiDocument.GetApiGroupNames()) { - var endpointsLocation = LocationFactory.CreateWithoutTemplateForApiGroupName(settings.EndpointsLocation); + var endpointsNamespace = NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.EndpointsNamespace); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, endpointsLocation); + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, endpointsNamespace); + + var endpointsLocation = LocationFactory.CreateWithoutTemplateForApiGroupName(settings.EndpointsLocation); var controllerParameters = ContentGeneratorServerEndpointParametersFactory.Create( operationSchemaMappings, @@ -364,7 +372,7 @@ public void MaintainGlobalUsings( { var requiredUsing = NamespaceFactory.Create( settings.ProjectName, - LocationFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation)); + LocationFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsNamespace)); if (!requiredUsings.Contains(requiredUsing, StringComparer.CurrentCulture)) { @@ -374,7 +382,7 @@ public void MaintainGlobalUsings( var apiGroupNames = openApiDocument.GetApiGroupNames(); - requiredUsings.AddRange(apiGroupNames.Select(x => NamespaceFactory.Create(settings.ProjectName, LocationFactory.CreateWithApiGroupName(x, settings.ContractsLocation)))); + requiredUsings.AddRange(apiGroupNames.Select(x => NamespaceFactory.Create(settings.ProjectName, NamespaceFactory.CreateWithApiGroupName(x, settings.ContractsNamespace)))); GlobalUsingsHelper.CreateOrUpdate( logger, @@ -390,7 +398,11 @@ private string GetRouteByApiGroupName( var (key, _) = openApiDocument.Paths.FirstOrDefault(x => x.IsPathStartingSegmentName(apiGroupName)); if (key is null) { - throw new NotSupportedException($"{nameof(apiGroupName)} was not found in any route."); + (key, _) = openApiDocument.Paths.FirstOrDefault(x => x.IsPathStartingApiGroupName(apiGroupName)); + if (key is null) + { + throw new NotSupportedException($"{nameof(apiGroupName)} was not found in any route."); + } } var routeSuffix = key @@ -404,9 +416,11 @@ private void GenerateEnumerationType( string enumerationName, OpenApiSchema openApiSchemaEnumeration) { - var contractsLocation = LocationFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation); + var contractsNamespace = NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsNamespace); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsLocation); + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); + + var contractsLocation = LocationFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation); var enumParameters = ContentGeneratorServerClientEnumParametersFactory.Create( codeGeneratorContentHeader, @@ -435,12 +449,16 @@ private void GenerateModel( string apiGroupName, bool isSharedContract) { + var contractsNamespace = isSharedContract + ? NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsNamespace) + : NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsNamespace); + + var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); + var contractsLocation = isSharedContract ? LocationFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation) : LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); - var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsLocation); - var parameters = ContentGeneratorServerClientModelParametersFactory.CreateForClass( codeGeneratorContentHeader, fullNamespace, diff --git a/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerDomainGenerator.cs b/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerDomainGenerator.cs index 284189913..3ec3417b8 100644 --- a/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerDomainGenerator.cs +++ b/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerDomainGenerator.cs @@ -154,7 +154,7 @@ public void MaintainGlobalUsings( var apiGroupNames = openApiDocument.GetApiGroupNames(); - requiredUsings.AddRange(apiGroupNames.Select(x => NamespaceFactory.Create(apiProjectName, LocationFactory.CreateWithApiGroupName(x, settings.ContractsLocation)))); + requiredUsings.AddRange(apiGroupNames.Select(x => NamespaceFactory.Create(apiProjectName, NamespaceFactory.CreateWithApiGroupName(x, settings.ContractsLocation)))); GlobalUsingsHelper.CreateOrUpdate( logger, diff --git a/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerHostTestGenerator.cs b/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerHostTestGenerator.cs index 5fda32d74..43a0e7573 100644 --- a/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerHostTestGenerator.cs +++ b/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerHostTestGenerator.cs @@ -277,7 +277,7 @@ public void MaintainGlobalUsings( if (operationSchemaMappings.Any(apiOperation => apiOperation.Model.IsShared)) { - requiredUsings.Add(NamespaceFactory.Create(apiProjectName, LocationFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation))); + requiredUsings.Add(NamespaceFactory.Create(apiProjectName, NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation))); } requiredUsings.Add("AutoFixture"); @@ -292,7 +292,7 @@ public void MaintainGlobalUsings( continue; } - requiredUsings.Add(NamespaceFactory.Create(apiProjectName, LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation))); + requiredUsings.Add(NamespaceFactory.Create(apiProjectName, NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation))); } GlobalUsingsHelper.CreateOrUpdate( diff --git a/src/Atc.Rest.ApiGenerator.OpenApi/Extensions/OpenApiPathItemExtensions.cs b/src/Atc.Rest.ApiGenerator.OpenApi/Extensions/OpenApiPathItemExtensions.cs index 6f5f9fb53..db404866e 100644 --- a/src/Atc.Rest.ApiGenerator.OpenApi/Extensions/OpenApiPathItemExtensions.cs +++ b/src/Atc.Rest.ApiGenerator.OpenApi/Extensions/OpenApiPathItemExtensions.cs @@ -16,6 +16,31 @@ public static string GetApiGroupName( }; } + public static bool IsPathStartingApiGroupName( + this KeyValuePair urlPath, string segmentName) + { + if (segmentName is null) + { + throw new ArgumentNullException(nameof(segmentName)); + } + + var sa = urlPath.Key.Split('/', StringSplitOptions.RemoveEmptyEntries); + if (string.IsNullOrEmpty(segmentName) && sa.Length == 0) + { + return true; + } + + if (sa.Length == 0) + { + return false; + } + + var apiGroupName = urlPath.GetApiGroupName(); + + return segmentName.Equals(apiGroupName, StringComparison.OrdinalIgnoreCase) || + segmentName.Equals(apiGroupName.EnsureSingular(), StringComparison.OrdinalIgnoreCase); + } + public static ApiAuthorizeModel? ExtractApiPathAuthorization( this OpenApiPathItem apiPath) { From e81074d7bf40581c8610a07e4a83ba701cbd71f2 Mon Sep 17 00:00:00 2001 From: David Kallesen Date: Mon, 13 Jan 2025 20:34:32 +0100 Subject: [PATCH 05/11] test: extend to handle contractsNamespace, endpointsNamespace and handlersNamespace --- .../ProjectGenerator/ServerApiGenerator.cs | 4 +- .../ProjectGenerator/ServerDomainGenerator.cs | 2 +- .../ServerHostTestGenerator.cs | 4 +- .../ProjectGenerator/ServerApiGenerator.cs | 4 +- .../ProjectGenerator/ServerDomainGenerator.cs | 2 +- .../ServerHostTestGenerator.cs | 4 +- .../ScenariosTests.cs | 150 +++++++++++++----- 7 files changed, 117 insertions(+), 53 deletions(-) diff --git a/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerApiGenerator.cs b/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerApiGenerator.cs index 95a4b2814..55e2b4a73 100644 --- a/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerApiGenerator.cs +++ b/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerApiGenerator.cs @@ -198,7 +198,7 @@ public void GenerateResults() { var apiGroupName = openApiPath.GetApiGroupName(); - var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsNamespace); var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); @@ -240,7 +240,7 @@ public void GenerateInterfaces() { var apiGroupName = openApiPath.GetApiGroupName(); - var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsNamespace); var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); diff --git a/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerDomainGenerator.cs b/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerDomainGenerator.cs index 83135a392..816eccffd 100644 --- a/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerDomainGenerator.cs +++ b/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerDomainGenerator.cs @@ -257,7 +257,7 @@ public void MaintainGlobalUsings( var apiGroupNames = openApiDocument.GetApiGroupNames(); - requiredUsings.AddRange(apiGroupNames.Select(x => NamespaceFactory.Create(apiProjectName, NamespaceFactory.CreateWithApiGroupName(x, settings.ContractsLocation)))); + requiredUsings.AddRange(apiGroupNames.Select(x => NamespaceFactory.Create(apiProjectName, NamespaceFactory.CreateWithApiGroupName(x, settings.ContractsNamespace)))); GlobalUsingsHelper.CreateOrUpdate( logger, diff --git a/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerHostTestGenerator.cs b/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerHostTestGenerator.cs index f2f3b292a..4ab5cdce5 100644 --- a/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerHostTestGenerator.cs +++ b/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerHostTestGenerator.cs @@ -275,7 +275,7 @@ public void MaintainGlobalUsings( if (operationSchemaMappings.Any(apiOperation => apiOperation.Model.IsShared)) { - requiredUsings.Add(NamespaceFactory.Create(apiProjectName, NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation))); + requiredUsings.Add(NamespaceFactory.Create(apiProjectName, NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsNamespace))); } var apiGroupNames = openApiDocument.GetApiGroupNames(); @@ -287,7 +287,7 @@ public void MaintainGlobalUsings( continue; } - requiredUsings.Add(NamespaceFactory.Create(apiProjectName, NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation))); + requiredUsings.Add(NamespaceFactory.Create(apiProjectName, NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsNamespace))); } GlobalUsingsHelper.CreateOrUpdate( diff --git a/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerApiGenerator.cs b/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerApiGenerator.cs index 5ea73d626..c91e4108f 100644 --- a/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerApiGenerator.cs +++ b/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerApiGenerator.cs @@ -214,7 +214,7 @@ public void GenerateResults() { var apiGroupName = openApiPath.GetApiGroupName(); - var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsNamespace); var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); @@ -256,7 +256,7 @@ public void GenerateInterfaces() { var apiGroupName = openApiPath.GetApiGroupName(); - var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var contractsNamespace = NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsNamespace); var fullNamespace = NamespaceFactory.Create(settings.ProjectName, contractsNamespace); diff --git a/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerDomainGenerator.cs b/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerDomainGenerator.cs index 3ec3417b8..73d01c586 100644 --- a/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerDomainGenerator.cs +++ b/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerDomainGenerator.cs @@ -154,7 +154,7 @@ public void MaintainGlobalUsings( var apiGroupNames = openApiDocument.GetApiGroupNames(); - requiredUsings.AddRange(apiGroupNames.Select(x => NamespaceFactory.Create(apiProjectName, NamespaceFactory.CreateWithApiGroupName(x, settings.ContractsLocation)))); + requiredUsings.AddRange(apiGroupNames.Select(x => NamespaceFactory.Create(apiProjectName, NamespaceFactory.CreateWithApiGroupName(x, settings.ContractsNamespace)))); GlobalUsingsHelper.CreateOrUpdate( logger, diff --git a/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerHostTestGenerator.cs b/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerHostTestGenerator.cs index 43a0e7573..5a3525c4f 100644 --- a/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerHostTestGenerator.cs +++ b/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerHostTestGenerator.cs @@ -277,7 +277,7 @@ public void MaintainGlobalUsings( if (operationSchemaMappings.Any(apiOperation => apiOperation.Model.IsShared)) { - requiredUsings.Add(NamespaceFactory.Create(apiProjectName, NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsLocation))); + requiredUsings.Add(NamespaceFactory.Create(apiProjectName, NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsNamespace))); } requiredUsings.Add("AutoFixture"); @@ -292,7 +292,7 @@ public void MaintainGlobalUsings( continue; } - requiredUsings.Add(NamespaceFactory.Create(apiProjectName, NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation))); + requiredUsings.Add(NamespaceFactory.Create(apiProjectName, NamespaceFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsNamespace))); } GlobalUsingsHelper.CreateOrUpdate( diff --git a/test/Atc.Rest.ApiGenerator.CLI.Tests/ScenariosTests.cs b/test/Atc.Rest.ApiGenerator.CLI.Tests/ScenariosTests.cs index 98c5b2f88..f1fc39452 100644 --- a/test/Atc.Rest.ApiGenerator.CLI.Tests/ScenariosTests.cs +++ b/test/Atc.Rest.ApiGenerator.CLI.Tests/ScenariosTests.cs @@ -53,33 +53,36 @@ public async Task ValidateYamlSpecificationByScenario( } [Theory] - [InlineData("DemoSample", AspNetOutputType.Mvc, false, null, null, null)] - [InlineData("DemoSample", AspNetOutputType.Mvc, true, null, null, null)] - [InlineData("ExAllResponseTypes", AspNetOutputType.Mvc, false, null, null, null)] - [InlineData("ExAllResponseTypes", AspNetOutputType.Mvc, true, null, null, null)] - [InlineData("ExAsyncEnumerable", AspNetOutputType.Mvc, false, null, null, null)] - [InlineData("ExAsyncEnumerable", AspNetOutputType.Mvc, true, null, null, null)] - [InlineData("ExAsyncEnumerable", AspNetOutputType.MinimalApi, false, null, null, null)] - [InlineData("ExAsyncEnumerable", AspNetOutputType.MinimalApi, true, null, null, null)] - [InlineData("ExGenericPagination", AspNetOutputType.Mvc, false, null, null, null)] - [InlineData("ExGenericPagination", AspNetOutputType.Mvc, true, null, null, null)] - [InlineData("ExNsWithTask", AspNetOutputType.Mvc, false, null, null, null)] - [InlineData("ExNsWithTask", AspNetOutputType.Mvc, true, null, null, null)] - [InlineData("ExUsers", AspNetOutputType.Mvc, false, null, null, null)] - [InlineData("ExUsers", AspNetOutputType.Mvc, true, null, null, null)] - [InlineData("PetStore", AspNetOutputType.Mvc, false, null, null, null)] - [InlineData("PetStore", AspNetOutputType.Mvc, true, null, null, null)] - [InlineData("Structure1", AspNetOutputType.Mvc, false, "[[apiGroupName]].MyContracts", "[[apiGroupName]].MyEndpoints", "[[apiGroupName]].MyHandlers")] - [InlineData("Structure1", AspNetOutputType.Mvc, true, "[[apiGroupName]].MyContracts", "[[apiGroupName]].MyEndpoints", "[[apiGroupName]].MyHandlers")] - [InlineData("Structure1", AspNetOutputType.MinimalApi, false, "[[apiGroupName]].MyContracts", "[[apiGroupName]].MyEndpoints", "[[apiGroupName]].MyHandlers")] - [InlineData("Structure1", AspNetOutputType.MinimalApi, true, "[[apiGroupName]].MyContracts", "[[apiGroupName]].MyEndpoints", "[[apiGroupName]].MyHandlers")] + [InlineData("DemoSample", AspNetOutputType.Mvc, false, null, null, null, null, null, null)] + [InlineData("DemoSample", AspNetOutputType.Mvc, true, null, null, null, null, null, null)] + [InlineData("ExAllResponseTypes", AspNetOutputType.Mvc, false, null, null, null, null, null, null)] + [InlineData("ExAllResponseTypes", AspNetOutputType.Mvc, true, null, null, null, null, null, null)] + [InlineData("ExAsyncEnumerable", AspNetOutputType.Mvc, false, null, null, null, null, null, null)] + [InlineData("ExAsyncEnumerable", AspNetOutputType.Mvc, true, null, null, null, null, null, null)] + [InlineData("ExAsyncEnumerable", AspNetOutputType.MinimalApi, false, null, null, null, null, null, null)] + [InlineData("ExAsyncEnumerable", AspNetOutputType.MinimalApi, true, null, null, null, null, null, null)] + [InlineData("ExGenericPagination", AspNetOutputType.Mvc, false, null, null, null, null, null, null)] + [InlineData("ExGenericPagination", AspNetOutputType.Mvc, true, null, null, null, null, null, null)] + [InlineData("ExNsWithTask", AspNetOutputType.Mvc, false, null, null, null, null, null, null)] + [InlineData("ExNsWithTask", AspNetOutputType.Mvc, true, null, null, null, null, null, null)] + [InlineData("ExUsers", AspNetOutputType.Mvc, false, null, null, null, null, null, null)] + [InlineData("ExUsers", AspNetOutputType.Mvc, true, null, null, null, null, null, null)] + [InlineData("PetStore", AspNetOutputType.Mvc, false, null, null, null, null, null, null)] + [InlineData("PetStore", AspNetOutputType.Mvc, true, null, null, null, null, null, null)] + [InlineData("Structure1", AspNetOutputType.Mvc, false, "[[apiGroupName]].MyContracts", "[[apiGroupName]].MyContracts", "[[apiGroupName]].MyEndpoints", "[[apiGroupName]].MyEndpoints", "[[apiGroupName]].MyHandlers", "[[apiGroupName]].MyHandlers")] + [InlineData("Structure1", AspNetOutputType.Mvc, true, "[[apiGroupName]].MyContracts", "[[apiGroupName]].MyContracts", "[[apiGroupName]].MyEndpoints", "[[apiGroupName]].MyEndpoints", "[[apiGroupName]].MyHandlers", "[[apiGroupName]].MyHandlers")] + [InlineData("Structure1", AspNetOutputType.MinimalApi, false, "[[apiGroupName]].MyContracts", "[[apiGroupName]].MyContracts", "[[apiGroupName]].MyEndpoints", "[[apiGroupName]].MyEndpoints", "[[apiGroupName]].MyHandlers", "[[apiGroupName]].MyHandlers")] + [InlineData("Structure1", AspNetOutputType.MinimalApi, true, "[[apiGroupName]].MyContracts", "[[apiGroupName]].MyContracts", "[[apiGroupName]].MyEndpoints", "[[apiGroupName]].MyEndpoints", "[[apiGroupName]].MyHandlers", "[[apiGroupName]].MyHandlers")] public async Task GenerateVerifyAndBuildForServerAllByScenario( string scenarioName, AspNetOutputType aspNetOutputType, bool useProblemDetailsAsDefaultResponseBody, string? contractsLocation, + string? contractsNamespace, string? endpointsLocation, - string? handlersLocation) + string? endpointsNamespace, + string? handlersLocation, + string? handlersNamespace) { // Arrange var scenarioPath = CollectScenarioPaths().First(x => x.Name == scenarioName); @@ -93,35 +96,50 @@ public async Task GenerateVerifyAndBuildForServerAllByScenario( } // Act & Assert - await AssertGenerateForServerAll(outputPath, scenarioPath, specificationFile, aspNetOutputType, useProblemDetailsAsDefaultResponseBody, contractsLocation, endpointsLocation, handlersLocation); + await AssertGenerateForServerAll( + outputPath, + scenarioPath, + specificationFile, + aspNetOutputType, + useProblemDetailsAsDefaultResponseBody, + contractsLocation, + contractsNamespace, + endpointsLocation, + endpointsNamespace, + handlersLocation, + handlersNamespace); + await AssertVerifyCsFilesForServerAll(outputPath, scenarioPath, aspNetOutputType, useProblemDetailsAsDefaultResponseBody); + await AssertBuildForServerAll(outputPath, scenarioPath); } [Theory] - [InlineData("DemoSample", false, false, null, null)] - [InlineData("DemoSample", true, false, null, null)] - [InlineData("ExAllResponseTypes", false, false, null, null)] - [InlineData("ExAllResponseTypes", true, false, null, null)] - [InlineData("ExAsyncEnumerable", false, false, null, null)] - [InlineData("ExAsyncEnumerable", true, false, null, null)] - [InlineData("ExGenericPagination", false, false, null, null)] - [InlineData("ExGenericPagination", true, false, null, null)] - [InlineData("ExNsWithTask", false, false, null, null)] - [InlineData("ExNsWithTask", true, false, null, null)] - [InlineData("ExUsers", false, false, null, null)] - [InlineData("ExUsers", true, false, null, null)] - [InlineData("PetStore", false, false, null, null)] - [InlineData("PetStore", true, false, null, null)] - [InlineData("Monta", false, true, null, null)] - [InlineData("Structure1", false, false, "[[apiGroupName]].MyContracts", "[[apiGroupName]].MyEndpoints")] - [InlineData("Structure1", true, false, "[[apiGroupName]].MyContracts", "[[apiGroupName]].MyEndpoints")] + [InlineData("DemoSample", false, false, null, null, null, null)] + [InlineData("DemoSample", true, false, null, null, null, null)] + [InlineData("ExAllResponseTypes", false, false, null, null, null, null)] + [InlineData("ExAllResponseTypes", true, false, null, null, null, null)] + [InlineData("ExAsyncEnumerable", false, false, null, null, null, null)] + [InlineData("ExAsyncEnumerable", true, false, null, null, null, null)] + [InlineData("ExGenericPagination", false, false, null, null, null, null)] + [InlineData("ExGenericPagination", true, false, null, null, null, null)] + [InlineData("ExNsWithTask", false, false, null, null, null, null)] + [InlineData("ExNsWithTask", true, false, null, null, null, null)] + [InlineData("ExUsers", false, false, null, null, null, null)] + [InlineData("ExUsers", true, false, null, null, null, null)] + [InlineData("PetStore", false, false, null, null, null, null)] + [InlineData("PetStore", true, false, null, null, null, null)] + [InlineData("Monta", false, true, null, null, null, null)] + [InlineData("Structure1", false, false, "[[apiGroupName]].MyContracts", "[[apiGroupName]].MyContracts", "[[apiGroupName]].MyEndpoints", "[[apiGroupName]].MyEndpoints")] + [InlineData("Structure1", true, false, "[[apiGroupName]].MyContracts", "[[apiGroupName]].MyContracts", "[[apiGroupName]].MyEndpoints", "[[apiGroupName]].MyEndpoints")] public async Task GenerateVerifyAndBuildForClientCSharpByScenario( string scenarioName, bool useProblemDetailsAsDefaultResponseBody, bool useCustomErrorResponseModel, string? contractsLocation, - string? endpointsLocation) + string? contractsNamespace, + string? endpointsLocation, + string? endpointsNamespace) { // Arrange var scenarioPath = CollectScenarioPaths().First(x => x.Name == scenarioName); @@ -136,7 +154,18 @@ public async Task GenerateVerifyAndBuildForClientCSharpByScenario( } // Act & Assert - await AssertGenerateForClientCSharp(outputPath, scenarioPath, specificationFile, optionsFile, useProblemDetailsAsDefaultResponseBody, useCustomErrorResponseModel, contractsLocation, endpointsLocation); + await AssertGenerateForClientCSharp( + outputPath, + scenarioPath, + specificationFile, + optionsFile, + useProblemDetailsAsDefaultResponseBody, + useCustomErrorResponseModel, + contractsLocation, + contractsNamespace, + endpointsLocation, + endpointsNamespace); + await AssertVerifyCsFilesForClientCSharp(outputPath, scenarioPath, useProblemDetailsAsDefaultResponseBody, useCustomErrorResponseModel); } @@ -261,8 +290,11 @@ private static async Task AssertGenerateForServerAll( AspNetOutputType aspNetOutputType, bool useProblemDetailsAsDefaultResponseBody, string? contractsLocation, + string? contractsNamespace, string? endpointsLocation, - string? handlersLocation) + string? endpointsNamespace, + string? handlersLocation, + string? handlersNamespace) { var sbCommands = new StringBuilder(); sbCommands.Append("generate server all"); @@ -289,18 +321,36 @@ private static async Task AssertGenerateForServerAll( sbCommands.Append(contractsLocation); } + if (contractsNamespace is not null) + { + sbCommands.Append(" --contractsNamespace "); + sbCommands.Append(contractsNamespace); + } + if (endpointsLocation is not null) { sbCommands.Append(" --endpointsLocation "); sbCommands.Append(endpointsLocation); } + if (endpointsNamespace is not null) + { + sbCommands.Append(" --endpointsNamespace "); + sbCommands.Append(endpointsNamespace); + } + if (handlersLocation is not null) { sbCommands.Append(" --handlersLocation "); sbCommands.Append(handlersLocation); } + if (handlersNamespace is not null) + { + sbCommands.Append(" --handlersNamespace "); + sbCommands.Append(handlersNamespace); + } + sbCommands.Append(" --verbose"); var (isSuccessful, output) = await ProcessHelper.Execute(cliExeFile!, sbCommands.ToString()); @@ -396,7 +446,9 @@ private static async Task AssertGenerateForClientCSharp( bool useProblemDetailsAsDefaultResponseBody, bool useCustomErrorResponseModel, string? contractsLocation, - string? endpointsLocation) + string? contractsNamespace, + string? endpointsLocation, + string? endpointsNamespace) { var sbCommands = new StringBuilder(); sbCommands.Append("generate client csharp"); @@ -424,12 +476,24 @@ private static async Task AssertGenerateForClientCSharp( sbCommands.Append(contractsLocation); } + if (contractsNamespace is not null) + { + sbCommands.Append(" --contractsNamespace "); + sbCommands.Append(contractsNamespace); + } + if (endpointsLocation is not null) { sbCommands.Append(" --endpointsLocation "); sbCommands.Append(endpointsLocation); } + if (endpointsNamespace is not null) + { + sbCommands.Append(" --endpointsNamespace "); + sbCommands.Append(endpointsNamespace); + } + sbCommands.Append(" --verbose"); var (isSuccessful, output) = await ProcessHelper.Execute(cliExeFile!, sbCommands.ToString()); From 9872274b28730c353f65474b84bc685a8ac8c606 Mon Sep 17 00:00:00 2001 From: David Kallesen Date: Tue, 14 Jan 2025 00:47:00 +0100 Subject: [PATCH 06/11] fix: GetDefaultValueInitializer with contractNamespaceWithoutApiGroupName if needed --- .../ClientCSharpApiGenerator.cs | 5 +++- .../ProjectGenerator/ServerApiGenerator.cs | 5 +++- .../ProjectGenerator/ServerApiGenerator.cs | 5 +++- ...neratorClientParameterParametersFactory.cs | 24 ++++++------------ ...neratorServerParameterParametersFactory.cs | 21 ++++++++++------ .../Extensions/OpenApiParameterExtensions.cs | 25 +++++++++++++++++++ .../GlobalUsings.cs | 1 + 7 files changed, 59 insertions(+), 27 deletions(-) diff --git a/src/Atc.Rest.ApiGenerator.Client.CSharp/ProjectGenerator/ClientCSharpApiGenerator.cs b/src/Atc.Rest.ApiGenerator.Client.CSharp/ProjectGenerator/ClientCSharpApiGenerator.cs index 278943078..54c7d9173 100644 --- a/src/Atc.Rest.ApiGenerator.Client.CSharp/ProjectGenerator/ClientCSharpApiGenerator.cs +++ b/src/Atc.Rest.ApiGenerator.Client.CSharp/ProjectGenerator/ClientCSharpApiGenerator.cs @@ -134,6 +134,8 @@ public void GenerateParameters() var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var contractNamespaceWithoutApiGroupName = NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsNamespace); + foreach (var openApiOperation in openApiPath.Value.Operations) { if (openApiOperation.Value.Deprecated && !settings.IncludeDeprecatedOperations) @@ -150,7 +152,8 @@ public void GenerateParameters() var parameterParameters = ContentGeneratorClientParameterParametersFactory.Create( fullNamespace, openApiOperation.Value, - openApiPath.Value.Parameters); + openApiPath.Value.Parameters, + contractNamespaceWithoutApiGroupName); var contentGenerator = new ContentGeneratorClientParameter( new GeneratedCodeHeaderGenerator(new GeneratedCodeGeneratorParameters(settings.Version)), diff --git a/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerApiGenerator.cs b/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerApiGenerator.cs index 55e2b4a73..cf4e89847 100644 --- a/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerApiGenerator.cs +++ b/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerApiGenerator.cs @@ -156,6 +156,8 @@ public void GenerateParameters() var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var contractNamespaceWithoutApiGroupName = NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsNamespace); + foreach (var openApiOperation in openApiPath.Value.Operations) { if (openApiOperation.Value.Deprecated && !settings.IncludeDeprecatedOperations) @@ -172,7 +174,8 @@ public void GenerateParameters() var parameterParameters = ContentGeneratorServerParameterParametersFactory.CreateForRecord( fullNamespace, openApiOperation.Value, - openApiPath.Value.Parameters); + openApiPath.Value.Parameters, + contractNamespaceWithoutApiGroupName); var contentGenerator = new ContentGenerators.ContentGeneratorServerParameter( new GeneratedCodeHeaderGenerator(new GeneratedCodeGeneratorParameters(settings.Version)), diff --git a/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerApiGenerator.cs b/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerApiGenerator.cs index c91e4108f..35f09a7e3 100644 --- a/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerApiGenerator.cs +++ b/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerApiGenerator.cs @@ -172,6 +172,8 @@ public void GenerateParameters() var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); + var contractNamespaceWithoutApiGroupName = NamespaceFactory.CreateWithoutTemplateForApiGroupName(settings.ContractsNamespace); + foreach (var openApiOperation in openApiPath.Value.Operations) { if (openApiOperation.Value.Deprecated && !settings.IncludeDeprecatedOperations) @@ -188,7 +190,8 @@ public void GenerateParameters() var parameterParameters = ContentGeneratorServerParameterParametersFactory.CreateForClass( fullNamespace, openApiOperation.Value, - openApiPath.Value.Parameters); + openApiPath.Value.Parameters, + contractNamespaceWithoutApiGroupName); var contentGenerator = new ContentGenerators.ContentGeneratorServerParameter( new GeneratedCodeHeaderGenerator(new GeneratedCodeGeneratorParameters(settings.Version)), diff --git a/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Client/ContentGeneratorClientParameterParametersFactory.cs b/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Client/ContentGeneratorClientParameterParametersFactory.cs index 2732baf9d..9110f4385 100644 --- a/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Client/ContentGeneratorClientParameterParametersFactory.cs +++ b/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Client/ContentGeneratorClientParameterParametersFactory.cs @@ -8,7 +8,8 @@ public static class ContentGeneratorClientParameterParametersFactory public static ContentGeneratorClientParameterParameters Create( string @namespace, OpenApiOperation openApiOperation, - IList globalPathParameters) + IList globalPathParameters, + string contractNamespaceWithoutApiGroupName) { ArgumentNullException.ThrowIfNull(openApiOperation); ArgumentNullException.ThrowIfNull(globalPathParameters); @@ -17,8 +18,8 @@ public static ContentGeneratorClientParameterParameters Create( var parameters = new List(); - AppendParameters(parameters, globalPathParameters); - AppendParameters(parameters, openApiOperation.Parameters); + AppendParameters(parameters, globalPathParameters, contractNamespaceWithoutApiGroupName); + AppendParameters(parameters, openApiOperation.Parameters, contractNamespaceWithoutApiGroupName); AppendParametersFromBody(parameters, openApiOperation.RequestBody); return new ContentGeneratorClientParameterParameters( @@ -32,14 +33,13 @@ public static ContentGeneratorClientParameterParameters Create( private static void AppendParameters( ICollection parameters, - IEnumerable openApiParameters) + IEnumerable openApiParameters, + string contractNamespaceWithoutApiGroupName) { foreach (var openApiParameter in openApiParameters) { var useListForDataType = openApiParameter.Schema.IsTypeArray(); - var parameterName = openApiParameter.Name.EnsureValidFormattedPropertyName(); - var dataType = useListForDataType ? openApiParameter.Schema.Items.GetDataType() : openApiParameter.Schema.GetDataType(); @@ -50,19 +50,11 @@ private static void AppendParameters( if (parameters.FirstOrDefault(x => x.Name == openApiParameter.Name) is null) { - var defaultValueInitializer = openApiParameter.Schema.GetDefaultValueAsString(); - - if (!string.IsNullOrEmpty(defaultValueInitializer) && - openApiParameter.ContainsEnumInSchemaOrProperties()) - { - defaultValueInitializer = dataType.Equals(parameterName, StringComparison.Ordinal) - ? $"{ContentGeneratorConstants.Contracts}.{dataType}.{defaultValueInitializer.PascalCase(ApiOperationExtractor.ModelNameSeparators, removeSeparators: true)}" - : $"{dataType}.{defaultValueInitializer.PascalCase(ApiOperationExtractor.ModelNameSeparators, removeSeparators: true)}"; - } + var defaultValueInitializer = openApiParameter.GetDefaultValueInitializer(contractNamespaceWithoutApiGroupName); parameters.Add(new ContentGeneratorClientParameterParametersProperty( openApiParameter.Name, - parameterName, + openApiParameter.Name.EnsureValidFormattedPropertyName(), openApiParameter.ExtractDocumentationTags(), dataType, isSimpleType, diff --git a/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Server/ContentGeneratorServerParameterParametersFactory.cs b/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Server/ContentGeneratorServerParameterParametersFactory.cs index 01de34df2..a3a925b7c 100644 --- a/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Server/ContentGeneratorServerParameterParametersFactory.cs +++ b/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Server/ContentGeneratorServerParameterParametersFactory.cs @@ -8,7 +8,8 @@ public static class ContentGeneratorServerParameterParametersFactory public static ContentGeneratorServerParameterParameters CreateForClass( string @namespace, OpenApiOperation openApiOperation, - IList globalPathParameters) + IList globalPathParameters, + string contractNamespaceWithoutApiGroupName) { ArgumentNullException.ThrowIfNull(openApiOperation); ArgumentNullException.ThrowIfNull(globalPathParameters); @@ -17,8 +18,8 @@ public static ContentGeneratorServerParameterParameters CreateForClass( var parameters = new List(); - AppendParameters(parameters, globalPathParameters); - AppendParameters(parameters, openApiOperation.Parameters); + AppendParameters(parameters, globalPathParameters, contractNamespaceWithoutApiGroupName); + AppendParameters(parameters, openApiOperation.Parameters, contractNamespaceWithoutApiGroupName); AppendParametersFromBody(parameters, openApiOperation.RequestBody); return new ContentGeneratorServerParameterParameters( @@ -33,7 +34,8 @@ public static ContentGeneratorServerParameterParameters CreateForClass( public static ContentGeneratorServerParameterParameters CreateForRecord( string @namespace, OpenApiOperation openApiOperation, - IList globalPathParameters) + IList globalPathParameters, + string contractNamespaceWithoutApiGroupName) { ArgumentNullException.ThrowIfNull(openApiOperation); ArgumentNullException.ThrowIfNull(globalPathParameters); @@ -42,8 +44,8 @@ public static ContentGeneratorServerParameterParameters CreateForRecord( var parameters = new List(); - AppendParameters(parameters, globalPathParameters); - AppendParameters(parameters, openApiOperation.Parameters); + AppendParameters(parameters, globalPathParameters, contractNamespaceWithoutApiGroupName); + AppendParameters(parameters, openApiOperation.Parameters, contractNamespaceWithoutApiGroupName); AppendParametersFromBody(parameters, openApiOperation.RequestBody); return new ContentGeneratorServerParameterParameters( @@ -57,7 +59,8 @@ public static ContentGeneratorServerParameterParameters CreateForRecord( private static void AppendParameters( ICollection parameters, - IEnumerable openApiParameters) + IEnumerable openApiParameters, + string contractNamespaceWithoutApiGroupName) { foreach (var openApiParameter in openApiParameters) { @@ -73,6 +76,8 @@ private static void AppendParameters( if (parameters.FirstOrDefault(x => x.Name == openApiParameter.Name) is null) { + var defaultValueInitializer = openApiParameter.GetDefaultValueInitializer(contractNamespaceWithoutApiGroupName); + parameters.Add(new ContentGeneratorServerParameterParametersProperty( openApiParameter.Name, openApiParameter.Name.EnsureValidFormattedPropertyName(), @@ -84,7 +89,7 @@ private static void AppendParameters( GetIsNullable(openApiParameter), openApiParameter.Required, GetAdditionalValidationAttributes(openApiParameter), - openApiParameter.Schema.GetDefaultValueAsString())); + defaultValueInitializer)); } } } diff --git a/src/Atc.Rest.ApiGenerator.OpenApi/Extensions/OpenApiParameterExtensions.cs b/src/Atc.Rest.ApiGenerator.OpenApi/Extensions/OpenApiParameterExtensions.cs index 0543afc80..1beac4a9f 100644 --- a/src/Atc.Rest.ApiGenerator.OpenApi/Extensions/OpenApiParameterExtensions.cs +++ b/src/Atc.Rest.ApiGenerator.OpenApi/Extensions/OpenApiParameterExtensions.cs @@ -32,6 +32,31 @@ public static bool ContainsEnumInSchemaOrProperties( apiParameter.Schema.OneOf.Any(oneOfSchema => oneOfSchema.IsSchemaEnumOrPropertyEnum()) || apiParameter.Schema.AnyOf.Any(anyOfSchema => anyOfSchema.IsSchemaEnumOrPropertyEnum()); + public static string? GetDefaultValueInitializer( + this OpenApiParameter openApiParameter, + string contractNamespaceWithoutApiGroupName) + { + var parameterName = openApiParameter.Name.EnsureValidFormattedPropertyName(); + + var useListForDataType = openApiParameter.Schema.IsTypeArray(); + + var dataType = useListForDataType + ? openApiParameter.Schema.Items.GetDataType() + : openApiParameter.Schema.GetDataType(); + + var defaultValueInitializer = openApiParameter.Schema.GetDefaultValueAsString(); + + if (!string.IsNullOrEmpty(defaultValueInitializer) && + openApiParameter.ContainsEnumInSchemaOrProperties()) + { + defaultValueInitializer = dataType.Equals(parameterName, StringComparison.Ordinal) + ? $"{contractNamespaceWithoutApiGroupName}.{dataType}.{defaultValueInitializer.PascalCase(ApiOperationExtractor.ModelNameSeparators, removeSeparators: true)}" + : $"{dataType}.{defaultValueInitializer.PascalCase(ApiOperationExtractor.ModelNameSeparators, removeSeparators: true)}"; + } + + return defaultValueInitializer; + } + public static CodeDocumentationTags ExtractDocumentationTags( this OpenApiParameter apiParameter) { diff --git a/src/Atc.Rest.ApiGenerator.OpenApi/GlobalUsings.cs b/src/Atc.Rest.ApiGenerator.OpenApi/GlobalUsings.cs index 2689646de..3f0215b44 100644 --- a/src/Atc.Rest.ApiGenerator.OpenApi/GlobalUsings.cs +++ b/src/Atc.Rest.ApiGenerator.OpenApi/GlobalUsings.cs @@ -6,6 +6,7 @@ global using System.Text; global using Atc.CodeDocumentation.CodeComment; +global using Atc.CodeGeneration.CSharp.Extensions; global using Atc.Data.Models; global using Atc.Rest.ApiGenerator.Contracts; global using Atc.Rest.ApiGenerator.Contracts.ContentGeneratorsParameters.Server; From 6e963217281fb31b8fb2d8e800c176d5380c5c33 Mon Sep 17 00:00:00 2001 From: David Kallesen Date: Tue, 14 Jan 2025 01:07:37 +0100 Subject: [PATCH 07/11] chore: update some nuget packages in NugetPackageReferenceProvider --- .../Providers/NugetPackageReferenceProvider.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Atc.Rest.ApiGenerator.Framework/Providers/NugetPackageReferenceProvider.cs b/src/Atc.Rest.ApiGenerator.Framework/Providers/NugetPackageReferenceProvider.cs index 764e22dc9..e50b9e7b4 100644 --- a/src/Atc.Rest.ApiGenerator.Framework/Providers/NugetPackageReferenceProvider.cs +++ b/src/Atc.Rest.ApiGenerator.Framework/Providers/NugetPackageReferenceProvider.cs @@ -19,18 +19,18 @@ public class NugetPackageReferenceProvider( { "AutoFixture", "4.18.1" }, { "AutoFixture.AutoNSubstitute", "4.18.1" }, { "AutoFixture.Xunit2", "4.18.1" }, - { "FluentAssertions", "6.12.0" }, + { "FluentAssertions", "7.0.0" }, { "FluentValidation.AspNetCore", "11.3.0" }, { "Microsoft.ApplicationInsights.AspNetCore", "2.22.0" }, { "Microsoft.AspNetCore.Authentication.JwtBearer", "8.0.4" }, { "Microsoft.AspNetCore.OpenApi", "8.0.6" }, { "Microsoft.AspNetCore.Mvc.Testing", "8.0.6" }, { "Microsoft.NETCore.Platforms", "7.0.4" }, - { "Microsoft.NET.Test.Sdk", "17.10.0" }, - { "NSubstitute", "5.1.0" }, + { "Microsoft.NET.Test.Sdk", "17.12.0" }, + { "NSubstitute", "5.3.0" }, { "Swashbuckle.AspNetCore", "7.0.0" }, - { "xunit", "2.9.2" }, - { "xunit.runner.visualstudio", "2.8.1" }, + { "xunit", "2.9.3" }, + { "xunit.runner.visualstudio", "3.0.1" }, }; public async Task GetAtcApiGeneratorVersion() From decb83efa92f25538de22edd951d423358aa6cab Mon Sep 17 00:00:00 2001 From: David Kallesen Date: Tue, 14 Jan 2025 01:08:11 +0100 Subject: [PATCH 08/11] fix: remove _ from body modelName --- .../ContentGeneratorServerParameterParametersFactory.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Server/ContentGeneratorServerParameterParametersFactory.cs b/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Server/ContentGeneratorServerParameterParametersFactory.cs index a3a925b7c..fe7e63a08 100644 --- a/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Server/ContentGeneratorServerParameterParametersFactory.cs +++ b/src/Atc.Rest.ApiGenerator.Framework/Factories/Parameters/Server/ContentGeneratorServerParameterParametersFactory.cs @@ -139,7 +139,7 @@ private static void AppendParametersFromBody( var requestBodyType = "string?"; if (requestSchema.Reference is not null) { - requestBodyType = requestSchema.Reference.Id.EnsureFirstCharacterToUpper(); + requestBodyType = requestSchema.Reference.Id.PascalCase(ApiOperationExtractor.ModelNameSeparators, removeSeparators: true); } else if (isFormatTypeOfBinary) { @@ -151,7 +151,7 @@ private static void AppendParametersFromBody( } else if (requestSchema.Items is not null) { - requestBodyType = requestSchema.Items.Reference.Id.EnsureFirstCharacterToUpper(); + requestBodyType = requestSchema.Items.Reference.Id.PascalCase(ApiOperationExtractor.ModelNameSeparators, removeSeparators: true); } parameters.Add(new ContentGeneratorServerParameterParametersProperty( From 1e9def3631801b2c405bda5d49832c3e6407dba7 Mon Sep 17 00:00:00 2001 From: David Kallesen Date: Tue, 14 Jan 2025 01:30:44 +0100 Subject: [PATCH 09/11] chore: remove unused contractNamespace parameter --- .../ContentGeneratorServerHandlerParametersFactory.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Atc.Rest.ApiGenerator.Framework.Minimal/Factories/ContentGeneratorServerHandlerParametersFactory.cs b/src/Atc.Rest.ApiGenerator.Framework.Minimal/Factories/ContentGeneratorServerHandlerParametersFactory.cs index 85faf73a2..982eb098b 100644 --- a/src/Atc.Rest.ApiGenerator.Framework.Minimal/Factories/ContentGeneratorServerHandlerParametersFactory.cs +++ b/src/Atc.Rest.ApiGenerator.Framework.Minimal/Factories/ContentGeneratorServerHandlerParametersFactory.cs @@ -4,12 +4,9 @@ public static class ContentGeneratorServerHandlerParametersFactory { public static ClassParameters Create( string @namespace, - string contractNamespace, OpenApiPathItem openApiPath, OpenApiOperation openApiOperation) { - ArgumentNullException.ThrowIfNull(openApiOperation); - var operationName = openApiOperation.GetOperationName(); var hasParameters = openApiPath.HasParameters() || From 172c9e3660826b383e917e5e951850124bc2def0 Mon Sep 17 00:00:00 2001 From: David Kallesen Date: Tue, 14 Jan 2025 01:31:19 +0100 Subject: [PATCH 10/11] chore: add missing Deprecated check for handlers --- .../ProjectGenerator/ServerDomainGenerator.cs | 7 +++++-- .../ProjectGenerator/ServerDomainGenerator.cs | 5 +++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerDomainGenerator.cs b/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerDomainGenerator.cs index 816eccffd..2c5c626d1 100644 --- a/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerDomainGenerator.cs +++ b/src/Atc.Rest.ApiGenerator.Framework.Minimal/ProjectGenerator/ServerDomainGenerator.cs @@ -108,15 +108,18 @@ public void ScaffoldHandlers() var apiGroupName = urlPath.GetApiGroupName(); var handlersLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.HandlersLocation); - var contractsLocation = LocationFactory.CreateWithApiGroupName(apiGroupName, settings.ContractsLocation); var fullNamespace = NamespaceFactory.Create(settings.ProjectName, handlersLocation); foreach (var openApiOperation in urlPath.Value.Operations) { + if (openApiOperation.Value.Deprecated && !settings.IncludeDeprecatedOperations) + { + continue; + } + var classParameters = ContentGeneratorServerHandlerParametersFactory.Create( fullNamespace, - $"Api.Generated.{contractsLocation}", // TODO: Fix this urlPath.Value, openApiOperation.Value); diff --git a/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerDomainGenerator.cs b/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerDomainGenerator.cs index 73d01c586..f64ca605a 100644 --- a/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerDomainGenerator.cs +++ b/src/Atc.Rest.ApiGenerator.Framework.Mvc/ProjectGenerator/ServerDomainGenerator.cs @@ -97,6 +97,11 @@ public void ScaffoldHandlers() foreach (var openApiOperation in urlPath.Value.Operations) { + if (openApiOperation.Value.Deprecated && !settings.IncludeDeprecatedOperations) + { + continue; + } + var classParameters = ContentGeneratorServerHandlerParametersFactory.Create( fullNamespace, urlPath.Value, From 5aac2e56902e0bbce2917d6787df6028c5f4de75 Mon Sep 17 00:00:00 2001 From: David Kallesen Date: Tue, 14 Jan 2025 01:41:02 +0100 Subject: [PATCH 11/11] docs: extend with contractsNamespace, endpointsNamespace and handlersNamespace --- README.md | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 1ac4aa093..d66a08536 100644 --- a/README.md +++ b/README.md @@ -211,8 +211,11 @@ OPTIONS: --disableCodingRules Disable ATC-Coding-Rules --useProblemDetailsAsDefaultResponseBody Use ProblemDetails as default responsen body --endpointsLocation [ENDPOINTSLOCATION] If endpoints-localtion is provided, generated files will be placed here instead of the Endpoints folder + --endpointsNamespace [ENDPOINTSNAMESPACE] If endpoints-namespace is provided, generated files will be placed here instead of the Endpoints namespace --contractsLocation [CONTRACTSLOCATION] If contracts-localtion is provided, generated files will be placed here instead of the Contracts folder + --contractsNamespace [CONTRACTSNAMESPACE] If contracts-namespace is provided, generated files will be placed here instead of the Contracts namespace --handlersLocation [HANDLERSLOCATION] If handlers-localtion is provided, generated files will be placed here instead of the Handlers folder + --handlersNamespace [HANDLERSNAMESPACE] If handlers-namespace is provided, generated files will be placed here instead of the Handlers namespace --usePartialClassForContracts Use Partial-Class for contracts --usePartialClassForEndpoints Use Partial-Class for endpoints --removeNamespaceGroupSeparatorInGlobalUsings Remove space between namespace groups in GlobalUsing.cs @@ -256,8 +259,11 @@ COMMANDS: "projectName": "", "projectSuffixName": "", "contractsLocation": "Contracts.[[apiGroupName]]", + "contractsNamespace": "Contracts.[[apiGroupName]]", "endpointsLocation": "Endpoints.[[apiGroupName]]", + "endpointsNamespace": "Endpoints.[[apiGroupName]]", "handlersLocation": "Handlers.[[apiGroupName]]", + "handlersNamespace": "Handlers.[[apiGroupName]]", "usePartialClassForContracts": false, "usePartialClassForEndpoints": false, "removeNamespaceGroupSeparatorInGlobalUsings": false, @@ -288,8 +294,11 @@ COMMANDS: "projectName": "", "projectSuffixName": "", "contractsLocation": "Contracts.[[apiGroupName]]", + "contractsNamespace": "Contracts.[[apiGroupName]]", "endpointsLocation": "Endpoints.[[apiGroupName]]", + "endpointsNamespace": "Endpoints.[[apiGroupName]]", "handlersLocation": "Handlers.[[apiGroupName]]", + "handlersNamespace": "Handlers.[[apiGroupName]]", "usePartialClassForContracts": false, "usePartialClassForEndpoints": false, "removeNamespaceGroupSeparatorInGlobalUsings": false, @@ -346,7 +355,7 @@ You can use specific syntax to define and customize the output file structure. ##### Syntax -For options like `contractsLocation`, `endpointsLocation`, and `handlersLocation`, +For options like `contractsLocation`, `contractsNamespace`, `endpointsLocation`, `endpointsNamespace`, `handlersLocation`, `handlersNamespace`, you can define paths using placeholders and custom directory names. The syntax is flexible and allows you to organize files based on grouping or specific requirements. @@ -355,13 +364,20 @@ The syntax is flexible and allows you to organize files based on grouping or spe | Option-Name | Option-Value | Example-file | Generated-output | |-------------|--------------|--------------|------------------| -| contractsLocation | Contracts | Account.cs | [Project-root]\Contracts\Accounts\Account.cs | -| contractsLocation | Contracts.[[apiGroupName]] | Account.cs | [Project-root]\Contracts\Accounts\Account.cs | -| contractsLocation | Contracts-[[apiGroupName]] | Account.cs | [Project-root]\Contracts\Accounts\Account.cs | -| contractsLocation | [[apiGroupName]].MyContracts | Account.cs | [Project-root]\Accounts\MyContracts\Account.cs | -| contractsLocation | [[apiGroupName]]-MyContracts | Account.cs | [Project-root]\Accounts\MyContracts\Account.cs | -| contractsLocation | [[apiGroupName]] | Account.cs | [Project-root]\Accounts\Account.cs | -| contractsLocation | . | Account.cs | [Project-root]\Account.cs | +| contractsLocation | Contracts | Account.cs | [Project-root]\Contracts\Accounts\Account.cs | +| contractsLocation | Contracts.[[apiGroupName]] | Account.cs | [Project-root]\Contracts\Accounts\Account.cs | +| contractsLocation | Contracts-[[apiGroupName]] | Account.cs | [Project-root]\Contracts\Accounts\Account.cs | +| contractsLocation | [[apiGroupName]].MyContracts | Account.cs | [Project-root]\Accounts\MyContracts\Account.cs | +| contractsLocation | [[apiGroupName]]-MyContracts | Account.cs | [Project-root]\Accounts\MyContracts\Account.cs | +| contractsLocation | [[apiGroupName]] | Account.cs | [Project-root]\Accounts\Account.cs | +| contractsLocation | . | Account.cs | [Project-root]\Account.cs | +| contractsNamespace | Contracts | Account.cs | [Project-root].Contracts.Accounts.Account.cs | +| contractsNamespace | Contracts.[[apiGroupName]] | Account.cs | [Project-root].Contracts.Accounts.Account.cs | +| contractsNamespace | Contracts-[[apiGroupName]] | Account.cs | [Project-root].Contracts.Accounts.Account.cs | +| contractsNamespace | [[apiGroupName]].MyContracts | Account.cs | [Project-root].Accounts.MyContracts.Account.cs | +| contractsNamespace | [[apiGroupName]]-MyContracts | Account.cs | [Project-root].Accounts.MyContracts.Account.cs | +| contractsNamespace | [[apiGroupName]] | Account.cs | [Project-root].Accounts.Account.cs | +| contractsNamespace | . | Account.cs | [Project-root].Account.cs | > Placeholder Explanation: >