[csharp] Options: useCollection, returnICollection

This change is inline with Microsoft's recommended guidelines for
collects
(https://msdn.microsoft.com/en-us/library/dn169389(v=vs.110).aspx).

Added generator options for csharp to:

* useCollection: Deserialize responses into and return Collection<T>
* returnICollection: For List<T> or Collection<T>, return ICollection<T>
  instead of the concrete type

As a consequence of useCollection, method imputs will also change to
Collection<T>.
This commit is contained in:
Jim Schubert
2016-01-23 16:22:26 -05:00
parent 421b70c259
commit 9dc40128ac
14 changed files with 94 additions and 3 deletions

View File

@@ -62,4 +62,9 @@ public class CodegenConstants {
public static final String OPTIONAL_ASSEMBLY_INFO = "optionalAssemblyInfo";
public static final String OPTIONAL_ASSEMBLY_INFO_DESC = "Generate AssemblyInfo.cs (Default: true).";
public static final String USE_COLLECTION = "useCollection";
public static final String USE_COLLECTION_DESC = "Deserialize array types to Collection<T> instead of List<T>.";
public static final String RETURN_ICOLLECTION = "returnICollection";
public static final String RETURN_ICOLLECTION_DESC = "Return ICollection<T> instead of the concrete type.";
}

View File

@@ -7,6 +7,7 @@ import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile;
import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.CodegenModel;
import io.swagger.codegen.CodegenOperation;
import io.swagger.models.properties.*;
import io.swagger.codegen.CliOption;
@@ -27,6 +28,8 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
protected boolean optionalAssemblyInfoFlag = true;
protected boolean optionalMethodArgumentFlag = true;
protected boolean useDateTimeOffsetFlag = false;
protected boolean useCollection = false;
protected boolean returnICollection = false;
protected String packageTitle = "Swagger Library";
protected String packageProductName = "SwaggerLibrary";
protected String packageDescription = "A library generated from a Swagger doc";
@@ -75,6 +78,8 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
"long?",
"float?",
"byte[]",
"ICollection",
"Collection",
"List",
"Dictionary",
"DateTime?",
@@ -88,7 +93,9 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
"Stream", // not really a primitive, we include it to avoid model import
"Object")
);
instantiationTypes.put("array", "List");
instantiationTypes.put("list", "List");
instantiationTypes.put("map", "Dictionary");
typeMapping = new HashMap<String, String>();
@@ -120,6 +127,11 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
CodegenConstants.OPTIONAL_ASSEMBLY_INFO_DESC).defaultValue(Boolean.TRUE.toString()));
cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, CodegenConstants.SOURCE_FOLDER_DESC).defaultValue(sourceFolder));
cliOptions.add(CliOption.newBoolean(CodegenConstants.USE_DATETIME_OFFSET, CodegenConstants.USE_DATETIME_OFFSET_DESC));
cliOptions.add( CliOption.newBoolean(CodegenConstants.USE_COLLECTION, CodegenConstants.USE_COLLECTION_DESC)
.defaultValue(Boolean.FALSE.toString()) );
cliOptions.add( CliOption.newBoolean(CodegenConstants.RETURN_ICOLLECTION, CodegenConstants.RETURN_ICOLLECTION_DESC)
.defaultValue(Boolean.FALSE.toString()) );
}
@Override
@@ -176,6 +188,14 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
.get(CodegenConstants.OPTIONAL_ASSEMBLY_INFO).toString()));
}
if (additionalProperties.containsKey(CodegenConstants.USE_COLLECTION)){
setUseCollection(Boolean.valueOf(additionalProperties.get(CodegenConstants.USE_COLLECTION).toString()));
}
if (additionalProperties.containsKey(CodegenConstants.RETURN_ICOLLECTION)){
setReturnICollection(Boolean.valueOf(additionalProperties.get(CodegenConstants.RETURN_ICOLLECTION).toString()));
}
supportingFiles.add(new SupportingFile("Configuration.mustache",
sourceFolder + File.separator + clientPackage.replace(".", java.io.File.separator), "Configuration.cs"));
supportingFiles.add(new SupportingFile("ApiClient.mustache",
@@ -289,6 +309,32 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
return toModelName(name);
}
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
super.postProcessOperations(objs);
if(objs != null) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation operation : ops) {
if (operation.returnType != null) {
operation.returnContainer = operation.returnType;
if( this.returnICollection && (
operation.returnType.startsWith("List")||
operation.returnType.startsWith("Collection")) ) {
// NOTE: ICollection works for both List<T> and Collection<T>
int genericStart = operation.returnType.indexOf("<");
if(genericStart > 0) {
operation.returnType = "ICollection" + operation.returnType.substring(genericStart);
}
}
}
}
}
}
return objs;
}
@Override
public String getTypeDeclaration(Property p) {
@@ -343,6 +389,21 @@ public class CSharpClientCodegen extends DefaultCodegen implements CodegenConfig
this.optionalMethodArgumentFlag = flag;
}
public void setReturnICollection(boolean returnICollection) {
this.returnICollection = returnICollection;
}
public void setUseCollection(boolean useCollection) {
this.useCollection = useCollection;
if(useCollection){
typeMapping.put("array", "Collection");
typeMapping.put("list", "Collection");
instantiationTypes.put("array", "Collection");
instantiationTypes.put("list", "Collection");
}
}
public void useDateTimeOffset(boolean flag) {
this.useDateTimeOffsetFlag = flag;
if (flag)