diff --git a/CHANGELOG.md b/CHANGELOG.md
index c61fa498be..a2d01b9be3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
+- Control generated type access modifier for C# via `--type-access-modifier` flag. [#4788](https://github.com/microsoft/kiota/issues/4788)
### Changed
diff --git a/src/Kiota.Builder/CodeDOM/AccessModifier.cs b/src/Kiota.Builder/CodeDOM/AccessModifier.cs
index b440fbca54..1ff57953d8 100644
--- a/src/Kiota.Builder/CodeDOM/AccessModifier.cs
+++ b/src/Kiota.Builder/CodeDOM/AccessModifier.cs
@@ -1,6 +1,7 @@
namespace Kiota.Builder.CodeDOM;
public enum AccessModifier
{
+ Internal = 3,
Public = 2,
Protected = 1,
Private = 0
diff --git a/src/Kiota.Builder/CodeDOM/CodeClass.cs b/src/Kiota.Builder/CodeDOM/CodeClass.cs
index 1e5be4b934..8ac263668e 100644
--- a/src/Kiota.Builder/CodeDOM/CodeClass.cs
+++ b/src/Kiota.Builder/CodeDOM/CodeClass.cs
@@ -30,9 +30,12 @@ public enum CodeClassKind
///
/// CodeClass represents an instance of a Class to be generated in source code
///
-public class CodeClass : ProprietableBlock, ITypeDefinition, IDiscriminatorInformationHolder, IDeprecableElement
+public class CodeClass : ProprietableBlock, ITypeDefinition, IDiscriminatorInformationHolder, IDeprecableElement, IAccessibleElement
{
private readonly ConcurrentDictionary PropertiesByWireName = new(StringComparer.OrdinalIgnoreCase);
+
+ public AccessModifier Access { get; set; } = AccessModifier.Public;
+
public bool IsErrorDefinition
{
get; set;
diff --git a/src/Kiota.Builder/CodeDOM/CodeEnum.cs b/src/Kiota.Builder/CodeDOM/CodeEnum.cs
index 3a46dd0a40..c4c48550e5 100644
--- a/src/Kiota.Builder/CodeDOM/CodeEnum.cs
+++ b/src/Kiota.Builder/CodeDOM/CodeEnum.cs
@@ -5,9 +5,10 @@
namespace Kiota.Builder.CodeDOM;
#pragma warning disable CA1711
-public class CodeEnum : CodeBlock, IDocumentedElement, ITypeDefinition, IDeprecableElement
+public class CodeEnum : CodeBlock, IDocumentedElement, ITypeDefinition, IDeprecableElement, IAccessibleElement
{
#pragma warning restore CA2227
+ public AccessModifier Access { get; set; } = AccessModifier.Public;
public bool Flags
{
get; set;
diff --git a/src/Kiota.Builder/Configuration/GenerationConfiguration.cs b/src/Kiota.Builder/Configuration/GenerationConfiguration.cs
index 6e81b63f23..352dd98b65 100644
--- a/src/Kiota.Builder/Configuration/GenerationConfiguration.cs
+++ b/src/Kiota.Builder/Configuration/GenerationConfiguration.cs
@@ -3,6 +3,7 @@
using System.IO;
using System.Linq;
using System.Text.Json.Nodes;
+using Kiota.Builder.CodeDOM;
using Kiota.Builder.Extensions;
using Kiota.Builder.Lock;
using Microsoft.OpenApi.ApiManifest;
@@ -38,6 +39,7 @@ public ConsumerOperation? Operation
public string ApiManifestPath { get; set; } = "apimanifest.json";
public string OutputPath { get; set; } = "./output";
public string ClientClassName { get; set; } = "ApiClient";
+ public AccessModifier TypeAccessModifier { get; set; } = AccessModifier.Public;
public string ClientNamespaceName { get; set; } = "ApiSdk";
public string NamespaceNameSeparator { get; set; } = ".";
public bool ExportPublicApi
diff --git a/src/Kiota.Builder/Lock/KiotaLock.cs b/src/Kiota.Builder/Lock/KiotaLock.cs
index a5d38c2fc4..671def487b 100644
--- a/src/Kiota.Builder/Lock/KiotaLock.cs
+++ b/src/Kiota.Builder/Lock/KiotaLock.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using Kiota.Builder.CodeDOM;
using Kiota.Builder.Configuration;
namespace Kiota.Builder.Lock;
@@ -31,6 +32,10 @@ public class KiotaLock
///
public string ClientClassName { get; set; } = string.Empty;
///
+ /// The type access modifier to use for the client types.
+ ///
+ public string TypeAccessModifier { get; set; } = "Public";
+ ///
/// The main namespace for this client.
///
public string ClientNamespaceName { get; set; } = string.Empty;
@@ -102,9 +107,11 @@ public void UpdateGenerationConfigurationFromLock(GenerationConfiguration config
{
ArgumentNullException.ThrowIfNull(config);
config.ClientClassName = ClientClassName;
- config.ClientNamespaceName = ClientNamespaceName;
if (Enum.TryParse(Language, out var parsedLanguage))
config.Language = parsedLanguage;
+ config.ClientNamespaceName = ClientNamespaceName;
+ if (Enum.TryParse(TypeAccessModifier, out var parsedAccessModifier))
+ config.TypeAccessModifier = parsedAccessModifier;
config.UsesBackingStore = UsesBackingStore;
config.ExcludeBackwardCompatible = ExcludeBackwardCompatible;
config.IncludeAdditionalData = IncludeAdditionalData;
@@ -132,6 +139,7 @@ public KiotaLock(GenerationConfiguration config)
ArgumentNullException.ThrowIfNull(config);
Language = config.Language.ToString();
ClientClassName = config.ClientClassName;
+ TypeAccessModifier = config.TypeAccessModifier.ToString();
ClientNamespaceName = config.ClientNamespaceName;
UsesBackingStore = config.UsesBackingStore;
ExcludeBackwardCompatible = config.ExcludeBackwardCompatible;
diff --git a/src/Kiota.Builder/Lock/KiotaLockComparer.cs b/src/Kiota.Builder/Lock/KiotaLockComparer.cs
index 26f156f74a..b2f9c7333e 100644
--- a/src/Kiota.Builder/Lock/KiotaLockComparer.cs
+++ b/src/Kiota.Builder/Lock/KiotaLockComparer.cs
@@ -35,6 +35,7 @@ public bool Equals(KiotaLock? x, KiotaLock? y)
&& _stringComparer.Equals(x.ClientClassName, y.ClientClassName)
&& _stringComparer.Equals(x.ClientNamespaceName, y.ClientNamespaceName)
&& _stringComparer.Equals(x.Language, y.Language)
+ && _stringComparer.Equals(x.TypeAccessModifier, y.TypeAccessModifier)
&& _stringIEnumerableDeepComparer.Equals(x.DisabledValidationRules, y.DisabledValidationRules)
&& _stringIEnumerableDeepComparer.Equals(x.Serializers, y.Serializers)
&& _stringIEnumerableDeepComparer.Equals(x.Deserializers, y.Deserializers)
@@ -56,6 +57,7 @@ public int GetHashCode([DisallowNull] KiotaLock obj)
hash.Add(obj.ClientClassName, _stringComparer);
hash.Add(obj.ClientNamespaceName, _stringComparer);
hash.Add(obj.Language, _stringComparer);
+ hash.Add(obj.TypeAccessModifier, _stringComparer);
hash.Add(obj.ExcludeBackwardCompatible);
hash.Add(obj.UsesBackingStore);
hash.Add(obj.IncludeAdditionalData);
diff --git a/src/Kiota.Builder/Refiners/CSharpRefiner.cs b/src/Kiota.Builder/Refiners/CSharpRefiner.cs
index 31c12c6bbe..c432dee00e 100644
--- a/src/Kiota.Builder/Refiners/CSharpRefiner.cs
+++ b/src/Kiota.Builder/Refiners/CSharpRefiner.cs
@@ -110,6 +110,7 @@ public override Task RefineAsync(CodeNamespace generatedCode, CancellationToken
generatedCode,
"IParseNode"
);
+ SetTypeAccessModifiers(generatedCode);
}, cancellationToken);
}
protected static void DisambiguatePropertiesWithClassNames(CodeElement currentElement)
@@ -260,4 +261,14 @@ protected static void CorrectIndexerType(CodeIndexer currentIndexer)
})
},
};
+
+ private void SetTypeAccessModifiers(CodeElement currentElement)
+ {
+ if (currentElement is IAccessibleElement accessibleElement and (CodeEnum or CodeClass))
+ {
+ accessibleElement.Access = _configuration.TypeAccessModifier;
+ }
+
+ CrawlTree(currentElement, SetTypeAccessModifiers);
+ }
}
diff --git a/src/Kiota.Builder/WorkspaceManagement/ApiClientConfiguration.cs b/src/Kiota.Builder/WorkspaceManagement/ApiClientConfiguration.cs
index a8441571fd..05fe7ed810 100644
--- a/src/Kiota.Builder/WorkspaceManagement/ApiClientConfiguration.cs
+++ b/src/Kiota.Builder/WorkspaceManagement/ApiClientConfiguration.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using Kiota.Builder.CodeDOM;
using Kiota.Builder.Configuration;
using Microsoft.OpenApi.ApiManifest;
@@ -15,6 +16,10 @@ public class ApiClientConfiguration : BaseApiConsumerConfiguration, ICloneable
///
public string Language { get; set; } = string.Empty;
///
+ /// The type access modifier to use for the client types.
+ ///
+ public string TypeAccessModifier { get; set; } = "Public";
+ ///
/// The structured mime types used for this client.
///
#pragma warning disable CA1002
@@ -64,6 +69,7 @@ public ApiClientConfiguration(GenerationConfiguration config) : base(config)
{
ArgumentNullException.ThrowIfNull(config);
Language = config.Language.ToString();
+ TypeAccessModifier = config.TypeAccessModifier.ToString();
ClientNamespaceName = config.ClientNamespaceName;
UsesBackingStore = config.UsesBackingStore;
ExcludeBackwardCompatible = config.ExcludeBackwardCompatible;
@@ -84,6 +90,8 @@ public void UpdateGenerationConfigurationFromApiClientConfiguration(GenerationCo
config.ClientNamespaceName = ClientNamespaceName;
if (Enum.TryParse(Language, out var parsedLanguage))
config.Language = parsedLanguage;
+ if (Enum.TryParse(TypeAccessModifier, out var parsedTypeAccessModifier))
+ config.TypeAccessModifier = parsedTypeAccessModifier;
config.UsesBackingStore = UsesBackingStore;
config.ExcludeBackwardCompatible = ExcludeBackwardCompatible;
config.IncludeAdditionalData = IncludeAdditionalData;
@@ -97,6 +105,7 @@ public object Clone()
var result = new ApiClientConfiguration
{
Language = Language,
+ TypeAccessModifier = TypeAccessModifier,
StructuredMimeTypes = [.. StructuredMimeTypes],
ClientNamespaceName = ClientNamespaceName,
UsesBackingStore = UsesBackingStore,
diff --git a/src/Kiota.Builder/WorkspaceManagement/ApiClientConfigurationComparer.cs b/src/Kiota.Builder/WorkspaceManagement/ApiClientConfigurationComparer.cs
index d13b5621cb..29e7a901dc 100644
--- a/src/Kiota.Builder/WorkspaceManagement/ApiClientConfigurationComparer.cs
+++ b/src/Kiota.Builder/WorkspaceManagement/ApiClientConfigurationComparer.cs
@@ -28,6 +28,7 @@ public override bool Equals(ApiClientConfiguration? x, ApiClientConfiguration? y
if (x.IncludeAdditionalData != y.IncludeAdditionalData) return false;
if (!_stringComparer.Equals(x.ClientNamespaceName, y.ClientNamespaceName)) return false;
if (!_stringComparer.Equals(x.Language, y.Language)) return false;
+ if (!_stringComparer.Equals(x.TypeAccessModifier, y.TypeAccessModifier)) return false;
// slow deep comparison
return _stringIEnumerableDeepComparer.Equals(x.DisabledValidationRules, y.DisabledValidationRules)
@@ -42,6 +43,7 @@ public override int GetHashCode([DisallowNull] ApiClientConfiguration obj)
hash.Add(obj.DisabledValidationRules, _stringIEnumerableDeepComparer); // _stringIEnumerableDeepComparer orders
hash.Add(obj.ClientNamespaceName, _stringComparer);
hash.Add(obj.Language, _stringComparer);
+ hash.Add(obj.TypeAccessModifier, _stringComparer);
hash.Add(obj.ExcludeBackwardCompatible);
hash.Add(obj.UsesBackingStore);
hash.Add(obj.IncludeAdditionalData);
diff --git a/src/Kiota.Builder/Writers/CSharp/CSharpConventionService.cs b/src/Kiota.Builder/Writers/CSharp/CSharpConventionService.cs
index 40baff16f0..46a6fda2f0 100644
--- a/src/Kiota.Builder/Writers/CSharp/CSharpConventionService.cs
+++ b/src/Kiota.Builder/Writers/CSharp/CSharpConventionService.cs
@@ -96,6 +96,7 @@ public override string GetAccessModifier(AccessModifier access)
{
return access switch
{
+ AccessModifier.Internal => "internal",
AccessModifier.Public => "public",
AccessModifier.Protected => "protected",
_ => "private",
diff --git a/src/Kiota.Builder/Writers/CSharp/CodeClassDeclarationWriter.cs b/src/Kiota.Builder/Writers/CSharp/CodeClassDeclarationWriter.cs
index f457430ec9..c7f3bdb808 100644
--- a/src/Kiota.Builder/Writers/CSharp/CodeClassDeclarationWriter.cs
+++ b/src/Kiota.Builder/Writers/CSharp/CodeClassDeclarationWriter.cs
@@ -41,7 +41,7 @@ public override void WriteCodeElement(ClassDeclaration codeElement, LanguageWrit
conventions.WriteDeprecationAttribute(parentClass, writer);
writer.WriteLine(GeneratedCodeAttribute);
if (!hasDescription) conventions.WritePragmaDisable(writer, CSharpConventionService.CS1591);
- writer.WriteLine($"public partial class {codeElement.Name.ToFirstCharacterUpperCase()} {derivation}");
+ writer.WriteLine($"{conventions.GetAccessModifier(parentClass.Access)} partial class {codeElement.Name.ToFirstCharacterUpperCase()} {derivation}");
if (!hasDescription) conventions.WritePragmaRestore(writer, CSharpConventionService.CS1591);
writer.StartBlock();
}
diff --git a/src/Kiota.Builder/Writers/CSharp/CodeEnumWriter.cs b/src/Kiota.Builder/Writers/CSharp/CodeEnumWriter.cs
index 588bb7db87..5b43dd3c44 100644
--- a/src/Kiota.Builder/Writers/CSharp/CodeEnumWriter.cs
+++ b/src/Kiota.Builder/Writers/CSharp/CodeEnumWriter.cs
@@ -37,7 +37,7 @@ public override void WriteCodeElement(CodeEnum codeElement, LanguageWriter write
writer.WriteLine("[Flags]");
conventions.WriteDeprecationAttribute(codeElement, writer);
if (!hasDescription) writer.WriteLine("#pragma warning disable CS1591");
- writer.WriteLine($"public enum {codeElement.Name.ToFirstCharacterUpperCase()}");
+ writer.WriteLine($"{conventions.GetAccessModifier(codeElement.Access)} enum {codeElement.Name.ToFirstCharacterUpperCase()}");
if (!hasDescription) writer.WriteLine("#pragma warning restore CS1591");
writer.StartBlock();
var idx = 0;
diff --git a/src/kiota/Handlers/Client/AddHandler.cs b/src/kiota/Handlers/Client/AddHandler.cs
index b7eb188e97..beec8f8058 100644
--- a/src/kiota/Handlers/Client/AddHandler.cs
+++ b/src/kiota/Handlers/Client/AddHandler.cs
@@ -2,6 +2,7 @@
using System.CommandLine.Invocation;
using System.Text.Json;
using Kiota.Builder;
+using Kiota.Builder.CodeDOM;
using Kiota.Builder.Configuration;
using Kiota.Builder.Extensions;
using Kiota.Builder.WorkspaceManagement;
@@ -27,6 +28,10 @@ public required Option LanguageOption
{
get; init;
}
+ public required Option TypeAccessModifierOption
+ {
+ get; init;
+ }
public required Option DescriptionOption
{
get; init;
@@ -69,6 +74,7 @@ public override async Task InvokeAsync(InvocationContext context)
{
string output = context.ParseResult.GetValueForOption(OutputOption) ?? string.Empty;
GenerationLanguage language = context.ParseResult.GetValueForOption(LanguageOption);
+ AccessModifier typeAccessModifier = context.ParseResult.GetValueForOption(TypeAccessModifierOption);
string openapi = context.ParseResult.GetValueForOption(DescriptionOption) ?? string.Empty;
bool backingStore = context.ParseResult.GetValueForOption(BackingStoreOption);
bool excludeBackwardCompatible = context.ParseResult.GetValueForOption(ExcludeBackwardCompatibleOption);
@@ -90,6 +96,7 @@ public override async Task InvokeAsync(InvocationContext context)
Configuration.Generation.IncludeAdditionalData = includeAdditionalData;
Configuration.Generation.Language = language;
WarnUsingPreviewLanguage(language);
+ Configuration.Generation.TypeAccessModifier = typeAccessModifier;
Configuration.Generation.SkipGeneration = skipGeneration;
Configuration.Generation.Operation = ConsumerOperation.Add;
if (includePatterns.Count != 0)
diff --git a/src/kiota/Handlers/Client/EditHandler.cs b/src/kiota/Handlers/Client/EditHandler.cs
index ae28990879..5c2bee3dfb 100644
--- a/src/kiota/Handlers/Client/EditHandler.cs
+++ b/src/kiota/Handlers/Client/EditHandler.cs
@@ -2,6 +2,7 @@
using System.CommandLine.Invocation;
using System.Text.Json;
using Kiota.Builder;
+using Kiota.Builder.CodeDOM;
using Kiota.Builder.Configuration;
using Kiota.Builder.Extensions;
using Kiota.Builder.WorkspaceManagement;
@@ -27,6 +28,10 @@ public required Option LanguageOption
{
get; init;
}
+ public required Option TypeAccessModifierOption
+ {
+ get; init;
+ }
public required Option DescriptionOption
{
get; init;
@@ -69,6 +74,7 @@ public override async Task InvokeAsync(InvocationContext context)
{
string output = context.ParseResult.GetValueForOption(OutputOption) ?? string.Empty;
GenerationLanguage? language = context.ParseResult.GetValueForOption(LanguageOption);
+ AccessModifier? typeAccessModifier = context.ParseResult.GetValueForOption(TypeAccessModifierOption);
string openapi = context.ParseResult.GetValueForOption(DescriptionOption) ?? string.Empty;
bool? backingStore = context.ParseResult.GetValueForOption(BackingStoreOption);
bool? excludeBackwardCompatible = context.ParseResult.GetValueForOption(ExcludeBackwardCompatibleOption);
@@ -109,6 +115,8 @@ public override async Task InvokeAsync(InvocationContext context)
clientConfiguration.UpdateGenerationConfigurationFromApiClientConfiguration(Configuration.Generation, className);
if (language.HasValue)
Configuration.Generation.Language = language.Value;
+ if (typeAccessModifier.HasValue)
+ Configuration.Generation.TypeAccessModifier = typeAccessModifier.Value;
if (backingStore.HasValue)
Configuration.Generation.UsesBackingStore = backingStore.Value;
if (excludeBackwardCompatible.HasValue)
diff --git a/src/kiota/Handlers/KiotaGenerateCommandHandler.cs b/src/kiota/Handlers/KiotaGenerateCommandHandler.cs
index a0442d81af..d44c035fdf 100644
--- a/src/kiota/Handlers/KiotaGenerateCommandHandler.cs
+++ b/src/kiota/Handlers/KiotaGenerateCommandHandler.cs
@@ -3,6 +3,7 @@
using System.Text.Json;
using Kiota.Builder;
+using Kiota.Builder.CodeDOM;
using Kiota.Builder.Extensions;
using Microsoft.Extensions.Logging;
@@ -27,6 +28,10 @@ public required Option ClassOption
{
get; init;
}
+ public required Option TypeAccessModifierOption
+ {
+ get; init;
+ }
public required Option NamespaceOption
{
get; init;
@@ -72,6 +77,7 @@ public override async Task InvokeAsync(InvocationContext context)
bool disableSSLValidation = context.ParseResult.GetValueForOption(DisableSSLValidationOption);
bool includeAdditionalData = context.ParseResult.GetValueForOption(AdditionalDataOption);
string className = context.ParseResult.GetValueForOption(ClassOption) ?? string.Empty;
+ AccessModifier typeAccessModifier = context.ParseResult.GetValueForOption(TypeAccessModifierOption);
string namespaceName = context.ParseResult.GetValueForOption(NamespaceOption) ?? string.Empty;
List serializer = context.ParseResult.GetValueForOption(SerializerOption) ?? [];
List deserializer = context.ParseResult.GetValueForOption(DeserializerOption) ?? [];
@@ -86,6 +92,7 @@ public override async Task InvokeAsync(InvocationContext context)
AssignIfNotNullOrEmpty(manifest, (c, s) => c.ApiManifestPath = s);
AssignIfNotNullOrEmpty(className, (c, s) => c.ClientClassName = s);
AssignIfNotNullOrEmpty(namespaceName, (c, s) => c.ClientNamespaceName = s);
+ Configuration.Generation.TypeAccessModifier = typeAccessModifier;
Configuration.Generation.UsesBackingStore = backingStore;
Configuration.Generation.ExcludeBackwardCompatible = excludeBackwardCompatible;
Configuration.Generation.IncludeAdditionalData = includeAdditionalData;
diff --git a/src/kiota/KiotaClientCommands.cs b/src/kiota/KiotaClientCommands.cs
index df7bced23a..cd912c3b90 100644
--- a/src/kiota/KiotaClientCommands.cs
+++ b/src/kiota/KiotaClientCommands.cs
@@ -33,6 +33,7 @@ public static Command GetAddCommand()
{
var defaultConfiguration = new GenerationConfiguration();
var languageOption = KiotaHost.GetLanguageOption();
+ var typeAccessModifierOption = KiotaHost.GetTypeAccessModifierOption();
var outputOption = KiotaHost.GetOutputPathOption(defaultConfiguration.OutputPath);
var descriptionOption = KiotaHost.GetDescriptionOption(defaultConfiguration.OpenAPIFilePath, true);
var namespaceOption = KiotaHost.GetNamespaceOption(defaultConfiguration.ClientNamespaceName);
@@ -50,6 +51,7 @@ public static Command GetAddCommand()
descriptionOption,
outputOption,
languageOption,
+ typeAccessModifierOption,
clientNameOption,
namespaceOption,
logLevelOption,
@@ -67,6 +69,7 @@ public static Command GetAddCommand()
DescriptionOption = descriptionOption,
OutputOption = outputOption,
LanguageOption = languageOption,
+ TypeAccessModifierOption = typeAccessModifierOption,
ClassOption = clientNameOption,
NamespaceOption = namespaceOption,
LogLevelOption = logLevelOption,
@@ -104,6 +107,7 @@ public static Command GetRemoveCommand()
public static Command GetEditCommand()
{
var languageOption = KiotaHost.GetOptionalLanguageOption();
+ var typeAccessModifierOption = KiotaHost.GetOptionalTypeAccessModifierOption();
var outputOption = KiotaHost.GetOutputPathOption(string.Empty);
var descriptionOption = KiotaHost.GetDescriptionOption(string.Empty);
var namespaceOption = KiotaHost.GetNamespaceOption(string.Empty);
@@ -121,6 +125,7 @@ public static Command GetEditCommand()
descriptionOption,
outputOption,
languageOption,
+ typeAccessModifierOption,
clientNameOption,
namespaceOption,
logLevelOption,
@@ -138,6 +143,7 @@ public static Command GetEditCommand()
DescriptionOption = descriptionOption,
OutputOption = outputOption,
LanguageOption = languageOption,
+ TypeAccessModifierOption = typeAccessModifierOption,
ClassOption = clientNameOption,
NamespaceOption = namespaceOption,
LogLevelOption = logLevelOption,
diff --git a/src/kiota/KiotaConfigurationExtensions.cs b/src/kiota/KiotaConfigurationExtensions.cs
index a4e241847c..c54572b1f6 100644
--- a/src/kiota/KiotaConfigurationExtensions.cs
+++ b/src/kiota/KiotaConfigurationExtensions.cs
@@ -1,4 +1,5 @@
using Kiota.Builder;
+using Kiota.Builder.CodeDOM;
using Kiota.Builder.Configuration;
using Microsoft.Extensions.Configuration;
@@ -54,6 +55,7 @@ public static void BindConfiguration(this KiotaConfiguration configObject, IConf
configObject.Generation.OpenAPIFilePath = configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.OpenAPIFilePath)}"] is string openApiFilePath && !string.IsNullOrEmpty(openApiFilePath) ? openApiFilePath : configObject.Generation.OpenAPIFilePath;
configObject.Generation.OutputPath = configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.OutputPath)}"] is string outputPath && !string.IsNullOrEmpty(outputPath) ? outputPath : configObject.Generation.OutputPath;
configObject.Generation.ClientClassName = configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.ClientClassName)}"] is string clientClassName && !string.IsNullOrEmpty(clientClassName) ? clientClassName : configObject.Generation.ClientClassName;
+ configObject.Generation.TypeAccessModifier = Enum.TryParse(configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.TypeAccessModifier)}"], true, out var accessModifier) ? accessModifier : AccessModifier.Public;
configObject.Generation.ClientNamespaceName = configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.ClientNamespaceName)}"] is string clientNamespaceName && !string.IsNullOrEmpty(clientNamespaceName) ? clientNamespaceName : configObject.Generation.ClientNamespaceName;
configObject.Generation.UsesBackingStore = bool.TryParse(configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.UsesBackingStore)}"], out var usesBackingStore) && usesBackingStore;
configObject.Generation.IncludeAdditionalData = bool.TryParse(configuration[$"{nameof(configObject.Generation)}:{nameof(GenerationConfiguration.IncludeAdditionalData)}"], out var includeAdditionalData) && includeAdditionalData;
diff --git a/src/kiota/KiotaHost.cs b/src/kiota/KiotaHost.cs
index 238406b020..a604cf5602 100644
--- a/src/kiota/KiotaHost.cs
+++ b/src/kiota/KiotaHost.cs
@@ -4,6 +4,7 @@
using kiota.Handlers;
using kiota.Rpc;
using Kiota.Builder;
+using Kiota.Builder.CodeDOM;
using Kiota.Builder.Configuration;
using Kiota.Builder.Validation;
using Microsoft.Extensions.Logging;
@@ -364,6 +365,21 @@ internal static Option GetLanguageOption()
AddEnumValidator(languageOption, "language");
return languageOption;
}
+ internal static Option GetTypeAccessModifierOption()
+ {
+ var accessOption = new Option("--type-access-modifier", "The type access modifier to use for the client types.");
+ accessOption.AddAlias("--tam");
+ accessOption.SetDefaultValue(AccessModifier.Public);
+ AddEnumValidator(accessOption, "type-access-modifier");
+ return accessOption;
+ }
+ internal static Option GetOptionalTypeAccessModifierOption()
+ {
+ var accessOption = new Option("--type-access-modifier", "The type access modifier to use for the client types.");
+ accessOption.AddAlias("--tam");
+ AddEnumValidator(accessOption, "type-access-modifier");
+ return accessOption;
+ }
internal static Option GetNamespaceOption(string defaultNamespaceName)
{
var namespaceOption = new Option("--namespace-name", () => defaultNamespaceName, "The namespace to use for the core client class specified with the --class-name option.");
@@ -432,6 +448,8 @@ private static Command GetGenerateCommand()
classOption.ArgumentHelpName = "name";
AddStringRegexValidator(classOption, classNameRegex(), "class name");
+ var typeAccessModifierOption = GetTypeAccessModifierOption();
+
var namespaceOption = GetNamespaceOption(defaultConfiguration.ClientNamespaceName);
var logLevelOption = GetLogLevelOption();
@@ -474,6 +492,7 @@ private static Command GetGenerateCommand()
outputOption,
languageOption,
classOption,
+ typeAccessModifierOption,
namespaceOption,
logLevelOption,
backingStoreOption,
@@ -496,6 +515,7 @@ private static Command GetGenerateCommand()
OutputOption = outputOption,
LanguageOption = languageOption,
ClassOption = classOption,
+ TypeAccessModifierOption = typeAccessModifierOption,
NamespaceOption = namespaceOption,
LogLevelOption = logLevelOption,
BackingStoreOption = backingStoreOption,
diff --git a/tests/Kiota.Builder.Tests/Refiners/CSharpLanguageRefinerTests.cs b/tests/Kiota.Builder.Tests/Refiners/CSharpLanguageRefinerTests.cs
index df29b9e80b..73fb546e0b 100644
--- a/tests/Kiota.Builder.Tests/Refiners/CSharpLanguageRefinerTests.cs
+++ b/tests/Kiota.Builder.Tests/Refiners/CSharpLanguageRefinerTests.cs
@@ -910,5 +910,23 @@ public async Task AddsUsingForUntypedNodeAsync()
Assert.Equal("Microsoft.Kiota.Abstractions.Serialization", nodeUsing[0].Declaration.Name);
}
+ [Theory]
+ [InlineData(AccessModifier.Public)]
+ [InlineData(AccessModifier.Internal)]
+ public async Task SetTypeAccessModifierAsync(AccessModifier accessModifier)
+ {
+ var codeClass = root.AddClass(new CodeClass
+ {
+ Name = "Class1",
+ Kind = CodeClassKind.Model
+ }).First();
+ var codeEnum = root.AddEnum(new CodeEnum
+ {
+ Name = "Enum1",
+ }).First();
+ await ILanguageRefiner.RefineAsync(new GenerationConfiguration { Language = GenerationLanguage.CSharp, TypeAccessModifier = accessModifier }, root);
+ Assert.Equal(codeClass.Access, accessModifier);
+ Assert.Equal(codeEnum.Access, accessModifier);
+ }
#endregion
}
diff --git a/tests/Kiota.Builder.Tests/WorkspaceManagement/ApiClientConfigurationComparerTests.cs b/tests/Kiota.Builder.Tests/WorkspaceManagement/ApiClientConfigurationComparerTests.cs
index f967f0b54b..161466ccc6 100644
--- a/tests/Kiota.Builder.Tests/WorkspaceManagement/ApiClientConfigurationComparerTests.cs
+++ b/tests/Kiota.Builder.Tests/WorkspaceManagement/ApiClientConfigurationComparerTests.cs
@@ -25,10 +25,11 @@ public void GetsHashCode()
var stringComparer = StringComparer.OrdinalIgnoreCase;
hash.Add(string.Empty, stringComparer);
hash.Add(string.Empty, stringComparer);
+ hash.Add("public", stringComparer);
hash.Add(false);
hash.Add(true);
hash.Add(false);
- hash.Add(new List(), iEnumComparer);
+ hash.Add([], iEnumComparer);
var hash2 = new HashCode();
hash2.Add(string.Empty, stringComparer);
hash2.Add(string.Empty, stringComparer);
diff --git a/tests/Kiota.Builder.Tests/Writers/CSharp/CodeClassDeclarationWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/CSharp/CodeClassDeclarationWriterTests.cs
index 20d0b3df68..836c5221e8 100644
--- a/tests/Kiota.Builder.Tests/Writers/CSharp/CodeClassDeclarationWriterTests.cs
+++ b/tests/Kiota.Builder.Tests/Writers/CSharp/CodeClassDeclarationWriterTests.cs
@@ -123,4 +123,15 @@ public void WritesGeneratedCodeAttribute()
var result = tw.ToString();
Assert.Matches(CodeEnumWriterTests.GeneratedCodePattern, result);
}
+
+ [Theory]
+ [InlineData(AccessModifier.Public)]
+ [InlineData(AccessModifier.Internal)]
+ public void WritesAccessModifier(AccessModifier accessModifier)
+ {
+ parentClass.Access = accessModifier;
+ codeElementWriter.WriteCodeElement(parentClass.StartBlock, writer);
+ var result = tw.ToString();
+ Assert.Contains($"{accessModifier.ToString().ToLower()} partial class", result);
+ }
}
diff --git a/tests/Kiota.Builder.Tests/Writers/CSharp/CodeEnumWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/CSharp/CodeEnumWriterTests.cs
index bbbd6fd2f5..0a76a2e617 100644
--- a/tests/Kiota.Builder.Tests/Writers/CSharp/CodeEnumWriterTests.cs
+++ b/tests/Kiota.Builder.Tests/Writers/CSharp/CodeEnumWriterTests.cs
@@ -139,4 +139,18 @@ public void WritesGeneratedCodeAttribute()
var result = tw.ToString();
Assert.Matches(GeneratedCodePattern, result);
}
+
+ [Theory]
+ [InlineData(AccessModifier.Public)]
+ [InlineData(AccessModifier.Internal)]
+ public void WritesAccessModifier(AccessModifier accessModifier)
+ {
+ currentEnum.Access = accessModifier;
+ currentEnum.AddOption(Option);
+ writer.Write(currentEnum);
+ var result = tw.ToString();
+ Assert.Contains($"{accessModifier.ToString().ToLower()} enum", result);
+ AssertExtensions.CurlyBracesAreClosed(result, 1);
+ Assert.Contains(Option.Name, result);
+ }
}