Skip to content

Commit

Permalink
Added feature to suppress the generation of the output of client clas…
Browse files Browse the repository at this point in the history
…ses and interfaces. (#4571)

* Added feature to suppress the generation of the output of client classes and interfaces.

* Added UI for SuppressClientClassesOutput and SuppressClientInterfacesOutput.

* Added documentation.
  • Loading branch information
paulomorgado authored Nov 21, 2023
1 parent de09331 commit 5e3e2c0
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ nswag run sample.nswag /runtime:Net50
"codeGenerators": {
"openApiToCSharpClient": {
"generateClientClasses": true,
"suppressClientClassesOutput": false,
"generateClientInterfaces": true,
"suppressClientInterfacesOutput": false,
"generateDtoTypes": true,
"injectHttpClient": true,
"disposeHttpClient": true,
Expand Down
52 changes: 52 additions & 0 deletions src/NSwag.CodeGeneration.CSharp.Tests/CSharpClientSettingsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,5 +173,57 @@ public async Task When_client_base_interface_is_specified_then_client_interface_
// Assert
Assert.Contains("public partial interface IFooClient : IClientBase", code);
}

[Fact]
public async Task When_client_class_generation_is_enabled_and_suppressed_then_client_class_is_not_generated()
{
// Arrange
var swaggerGenerator = new WebApiOpenApiDocumentGenerator(new WebApiOpenApiDocumentGeneratorSettings
{
SchemaSettings = new NewtonsoftJsonSchemaGeneratorSettings()
});

var document = await swaggerGenerator.GenerateForControllerAsync<FooController>();
var generator = new CSharpClientGenerator(document, new CSharpClientGeneratorSettings
{
GenerateClientClasses = true,
SuppressClientClassesOutput = true,
GenerateClientInterfaces = true,
// SuppressClientInterfacesOutput = false, // default
});

// Act
var code = generator.GenerateFile();

// Assert
Assert.Contains("public partial interface IFooClient", code);
Assert.DoesNotContain("public partial class FooClient : IFooClient", code);
}

[Fact]
public async Task When_client_interface_generation_is_enabled_and_suppressed_then_client_interface_is_not_generated()
{
// Arrange
var swaggerGenerator = new WebApiOpenApiDocumentGenerator(new WebApiOpenApiDocumentGeneratorSettings
{
SchemaSettings = new NewtonsoftJsonSchemaGeneratorSettings()
});

var document = await swaggerGenerator.GenerateForControllerAsync<FooController>();
var generator = new CSharpClientGenerator(document, new CSharpClientGeneratorSettings
{
GenerateClientClasses = true,
// SuppressClientClassesOutput = false, // default
GenerateClientInterfaces = true,
SuppressClientInterfacesOutput = true,
});

// Act
var code = generator.GenerateFile();

// Assert
Assert.DoesNotContain("public partial interface IFooClient", code);
Assert.Contains("public partial class FooClient : IFooClient", code);
}
}
}
9 changes: 6 additions & 3 deletions src/NSwag.CodeGeneration.CSharp/CSharpClientGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,17 @@ protected override IEnumerable<CodeArtifact> GenerateClientTypes(string controll
var model = new CSharpClientTemplateModel(controllerName, controllerClassName, operations, exceptionSchema, _document, Settings);
if (model.HasOperations)
{
if (model.GenerateClientInterfaces)
if (model.GenerateClientInterfaces && !model.SuppressClientInterfacesOutput)
{
var interfaceTemplate = Settings.CSharpGeneratorSettings.TemplateFactory.CreateTemplate("CSharp", "Client.Interface", model);
yield return new CodeArtifact(model.Class, CodeArtifactType.Class, CodeArtifactLanguage.CSharp, CodeArtifactCategory.Contract, interfaceTemplate);
}

var classTemplate = Settings.CSharpGeneratorSettings.TemplateFactory.CreateTemplate("CSharp", "Client.Class", model);
yield return new CodeArtifact(model.Class, CodeArtifactType.Class, CodeArtifactLanguage.CSharp, CodeArtifactCategory.Client, classTemplate);
if (!model.SuppressClientClassesOutput)
{
var classTemplate = Settings.CSharpGeneratorSettings.TemplateFactory.CreateTemplate("CSharp", "Client.Class", model);
yield return new CodeArtifact(model.Class, CodeArtifactType.Class, CodeArtifactLanguage.CSharp, CodeArtifactCategory.Client, classTemplate);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ public CSharpClientTemplateModel(
/// <summary>Gets a value indicating whether to generate client interfaces.</summary>
public bool GenerateClientInterfaces => _settings.GenerateClientInterfaces;

/// <summary>Gets a value indicating whether to generate the output of client interfaces.</summary>
public bool SuppressClientInterfacesOutput => _settings.SuppressClientInterfacesOutput;

/// <summary>Gets a value indicating whether to generate the output of client classes.</summary>
public bool SuppressClientClassesOutput => _settings.SuppressClientClassesOutput;

/// <summary>Gets client base interface.</summary>
public string ClientBaseInterface => _settings.ClientBaseInterface;

Expand Down
8 changes: 8 additions & 0 deletions src/NSwag.CodeGeneration/ClientGeneratorBaseSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public abstract class ClientGeneratorBaseSettings
protected ClientGeneratorBaseSettings()
{
GenerateClientClasses = true;
SuppressClientClassesOutput = false;
SuppressClientInterfacesOutput = false;
GenerateDtoTypes = true;

OperationNameGenerator = new MultipleClientsFromOperationIdOperationNameGenerator();
Expand All @@ -43,9 +45,15 @@ protected ClientGeneratorBaseSettings()
/// <summary>Gets or sets a value indicating whether to generate interfaces for the client classes (default: false).</summary>
public bool GenerateClientInterfaces { get; set; }

/// <summary>Gets or sets a value indicating whether to generate the output of interfaces for the client classes (default: false).</summary>
public bool SuppressClientInterfacesOutput { get; set; }

/// <summary>Gets or sets a value indicating whether to generate client types (default: true).</summary>
public bool GenerateClientClasses { get; set; }

/// <summary>Gets or sets a value indicating whether to generate the output of client types (default: false).</summary>
public bool SuppressClientClassesOutput { get; set; }

/// <summary>Gets or sets the operation name generator.</summary>
public IOperationNameGenerator OperationNameGenerator { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,27 @@ public bool GenerateClientClasses
set { Settings.GenerateClientClasses = value; }
}

[Argument(Name = "SuppressClientClassesOutput", IsRequired = false, Description = "Specifies whether generate output for client classes.")]
public bool SuppressClientClassesOutput
{
get { return Settings.SuppressClientClassesOutput; }
set { Settings.SuppressClientClassesOutput = value; }
}

[Argument(Name = "GenerateClientInterfaces", IsRequired = false, Description = "Specifies whether generate interfaces for the client classes.")]
public bool GenerateClientInterfaces
{
get { return Settings.GenerateClientInterfaces; }
set { Settings.GenerateClientInterfaces = value; }
}

[Argument(Name = "SuppressClientInterfacesOutput", IsRequired = false, Description = "Specifies whether generate output for interfaces for the client classes.")]
public bool SuppressClientInterfacesOutput
{
get { return Settings.SuppressClientInterfacesOutput; }
set { Settings.SuppressClientInterfacesOutput = value; }
}

[Argument(Name = "ClientBaseInterface", IsRequired = false, Description = "Base interface for client interfaces (empty for no client base interface).")]
public string ClientBaseInterface
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@
ToolTip="GenerateClientClasses"
Content="Generate Client Classes" Margin="0,0,0,12" />

<CheckBox IsChecked="{Binding Command.SuppressClientClassesOutput, Mode=TwoWay}"
ToolTip="SuppressClientClassesOutput"
Content="Suppress output of generated Client Classes" Margin="0,0,0,12" />

<StackPanel Visibility="{Binding Command.GenerateClientClasses, Converter={StaticResource VisibilityConverter}}">
<TextBlock Margin="0,0,0,6" TextWrapping="Wrap">
<Run Text="Operation Generation Mode" FontWeight="Bold" />
Expand Down Expand Up @@ -154,6 +158,10 @@
ToolTip="GenerateClientInterfaces"
Content="Generate interfaces for Client classes" Margin="0,0,0,12" />

<CheckBox IsChecked="{Binding Command.SuppressClientInterfacesOutput, Mode=TwoWay}"
ToolTip="SuppressClientInterfacesOutput"
Content="Suppress output of generated interfaces for Client classes" Margin="0,0,0,12" />

<TextBlock Text="Base interface for Client Interfaces (optional)" FontWeight="Bold" Margin="0,0,0,6"
Visibility="{Binding Command.GenerateClientInterfaces, Converter={StaticResource VisibilityConverter}}" />
<TextBox Text="{Binding Command.ClientBaseInterface, Mode=TwoWay}"
Expand Down

0 comments on commit 5e3e2c0

Please sign in to comment.