[csharp] Support internal access of generated code (#4560)

Allows users to specify 'nonPublicApi' additional property (and C#
client CLI switch) to reduce visibility of classes created by the
generator. This includes API and Models as well as supporting code like
ApiClient and other infrastructure.

The requirement is to support codegen generated code to be embedded
within other applications where the generated code is not intended to be
publicly consumable or publicy exposed. An example would be an SDK which
internally consumes an API via the generated code; we wouldn't want the
internal API implementation exposed as part of that SDK.

Reducing visibility of the classes effectively makes the entire
implementation internal, regardless of the public modifier on methods or
static members. To fully make all members internal it would require
explicit interface implementation, which is not ideal.

see #4401
This commit is contained in:
Jim Schubert
2017-01-15 11:19:10 -06:00
committed by wing328
parent 23c5376ed6
commit d97b1da90c
16 changed files with 43 additions and 13 deletions

View File

@@ -144,4 +144,7 @@ public class CodegenConstants {
public static final String GENERATE_PROPERTY_CHANGED = "generatePropertyChanged";
public static final String GENERATE_PROPERTY_CHANGED_DESC = "Specifies that models support raising property changed events.";
public static final String NON_PUBLIC_API = "nonPublicApi";
public static final String NON_PUBLIC_API_DESC = "Generates code with reduced access modifiers; allows embedding elsewhere without exposing non-public API calls to consumers.";
}

View File

@@ -45,6 +45,9 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
protected Map<Character, String> regexModifiers;
protected final Map<String, String> frameworks;
// By default, generated code is considered public
protected boolean nonPublicApi = Boolean.FALSE;
public CSharpClientCodegen() {
super();
modelTemplateFiles.put("model.mustache", ".cs");
@@ -130,6 +133,14 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
CodegenConstants.PACKAGE_DESCRIPTION_DESC,
this.generatePropertyChanged);
// NOTE: This will reduce visibility of all public members in templates. Users can use InternalsVisibleTo
// https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute(v=vs.110).aspx
// to expose to shared code if the generated code is not embedded into another project. Otherwise, users of codegen
// should rely on default public visibility.
addSwitch(CodegenConstants.NON_PUBLIC_API,
CodegenConstants.NON_PUBLIC_API_DESC,
this.nonPublicApi);
regexModifiers = new HashMap<Character, String>();
regexModifiers.put('i', "IgnoreCase");
regexModifiers.put('m', "Multiline");
@@ -232,6 +243,10 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
.get(CodegenConstants.OPTIONAL_ASSEMBLY_INFO).toString()));
}
if (additionalProperties.containsKey(CodegenConstants.NON_PUBLIC_API)) {
setNonPublicApi(Boolean.valueOf(additionalProperties.get(CodegenConstants.NON_PUBLIC_API).toString()));
}
final String testPackageName = testPackageName();
String packageFolder = sourceFolder + File.separator + packageName;
String clientPackageDir = packageFolder + File.separator + clientPackage;
@@ -555,6 +570,14 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
this.generatePropertyChanged = generatePropertyChanged;
}
public boolean isNonPublicApi() {
return nonPublicApi;
}
public void setNonPublicApi(final boolean nonPublicApi) {
this.nonPublicApi = nonPublicApi;
}
@Override
public String toModelDocFilename(String name) {
return toModelFilename(name);