Skip to content

Commit 05a63ef

Browse files
author
Balakrishnan Ranganathan
committed
Move more functions to different classes
1 parent 3a4b832 commit 05a63ef

7 files changed

Lines changed: 272 additions & 263 deletions

File tree

src/WebApiToTypeScript/Interfaces/InterfaceService.cs

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,15 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using WebApiToTypeScript.Block;
5-
using WebApiToTypeScript.Enums;
65
using WebApiToTypeScript.Types;
76

87
namespace WebApiToTypeScript.Interfaces
98
{
10-
public class InterfaceService
9+
public class InterfaceService : ServiceAware
1110
{
12-
private Config.Config Config { get; }
13-
14-
private readonly TypeService typeService;
15-
private readonly EnumsService enumsService;
16-
1711
private InterfaceNode InterfaceNode { get; }
1812
= new InterfaceNode();
1913

20-
public InterfaceService(
21-
Config.Config config,
22-
TypeService typeService,
23-
EnumsService enumsService)
24-
{
25-
Config = config;
26-
27-
this.typeService = typeService;
28-
this.enumsService = enumsService;
29-
}
30-
31-
3214
public TypeScriptBlock WriteInterfacesToBlock(TypeScriptBlock interfacesBlock)
3315
{
3416
WriteInterfaces(interfacesBlock, InterfaceNode);
@@ -56,13 +38,13 @@ public InterfaceNode AddInterfaceNode(TypeDefinition typeDefinition)
5638
{
5739
var thingType = thing.CSharpType.TypeDefinition;
5840

59-
var primitiveType = typeService.GetPrimitiveTypeScriptType(thingType.FullName);
41+
var primitiveType = TypeService.GetPrimitiveTypeScriptType(thingType.FullName);
6042
if (primitiveType != null)
6143
continue;
6244

6345
if (thingType.IsEnum && Config.GenerateEnums)
6446
{
65-
enumsService.AddEnum(thingType);
47+
EnumsService.AddEnum(thingType);
6648
}
6749
else if (!thingType.IsPrimitive)
6850
{
@@ -97,7 +79,7 @@ private void WriteInterfaces(TypeScriptBlock interfacesBlock, InterfaceNode inte
9779
var thingType = thing.CSharpType.TypeDefinition;
9880
var collectionString = thing.CSharpType.IsCollection ? "[]" : string.Empty;
9981

100-
var primitiveType = typeService.GetPrimitiveTypeScriptType(thingType.FullName);
82+
var primitiveType = TypeService.GetPrimitiveTypeScriptType(thingType.FullName);
10183
if (primitiveType != null)
10284
{
10385
constructorParameters.Add($"{thing.Name}?: {primitiveType}{collectionString}");
@@ -144,15 +126,15 @@ private List<MemberWithCSharpType> GetMembers(TypeDefinition typeDefinition)
144126
.Select(p => new MemberWithCSharpType
145127
{
146128
Name = p.Name,
147-
CSharpType = typeService.GetCSharpType(p.FieldType)
129+
CSharpType = TypeService.GetCSharpType(p.FieldType)
148130
});
149131

150132
var properties = typeDefinition.Properties
151133
.Where(p => !p.IsSpecialName && p.SetMethod != null)
152134
.Select(p => new MemberWithCSharpType
153135
{
154136
Name = p.Name,
155-
CSharpType = typeService.GetCSharpType(p.PropertyType)
137+
CSharpType = TypeService.GetCSharpType(p.PropertyType)
156138
});
157139

158140
return fields.Union(properties)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using WebApiToTypeScript.Enums;
2+
using WebApiToTypeScript.Types;
3+
4+
namespace WebApiToTypeScript.Interfaces
5+
{
6+
public abstract class ServiceAware
7+
{
8+
protected TypeService TypeService
9+
=> WebApiToTypeScript.TypeService;
10+
11+
protected EnumsService EnumsService
12+
=> WebApiToTypeScript.EnumsService;
13+
14+
protected InterfaceService InterfaceService
15+
=> WebApiToTypeScript.InterfaceService;
16+
17+
public Config.Config Config
18+
=> WebApiToTypeScript.Config;
19+
}
20+
}

src/WebApiToTypeScript/Types/TypeService.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,20 @@ public List<TypeDefinition> GetControllers(string webApiModuleFilePath)
6363
.ToList();
6464
}
6565

66+
public bool IsNullable(TypeReference type)
67+
{
68+
var genericType = type as GenericInstanceType;
69+
return genericType != null
70+
&& genericType.FullName.StartsWith("System.Nullable`1");
71+
}
72+
73+
public bool IsParameterOptional(ParameterDefinition parameter)
74+
{
75+
return parameter.IsOptional
76+
|| !parameter.ParameterType.IsValueType
77+
|| IsNullable(parameter.ParameterType);
78+
}
79+
6680
private bool IsControllerType(TypeDefinition type)
6781
{
6882
var apiControllerType = "System.Web.Http.ApiController";

src/WebApiToTypeScript/WebApi/WebApiAction.cs

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
using Mono.Cecil;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using WebApiToTypeScript.Interfaces;
45
using WebApiToTypeScript.Types;
56

67
namespace WebApiToTypeScript.WebApi
78
{
8-
public class WebApiAction
9+
public class WebApiAction : ServiceAware
910
{
1011
public string Name { get; set; }
1112
public string Route { get; set; }
@@ -56,6 +57,102 @@ public string GetActionNameForVerb(WebApiHttpVerb verb)
5657
return $"{Name}{verbPostfix}";
5758
}
5859

60+
public string GetCallArgumentValue(WebApiHttpVerb verb)
61+
{
62+
var isFormBody = verb == WebApiHttpVerb.Post || verb == WebApiHttpVerb.Put;
63+
64+
var callArgumentValueString = BodyParameters
65+
.Select(routePart =>
66+
{
67+
var typeScriptType = routePart.GetTypeScriptType()
68+
.TypeName;
69+
70+
var valueFormat = $"{routePart.Name}";
71+
72+
switch (typeScriptType)
73+
{
74+
case "string":
75+
valueFormat = $"`\"${{{routePart.Name}}}\"`";
76+
break;
77+
}
78+
79+
return $"{routePart.Name} != null ? {valueFormat} : null";
80+
})
81+
.SingleOrDefault();
82+
83+
return (!isFormBody || string.IsNullOrEmpty(callArgumentValueString))
84+
? "null"
85+
: callArgumentValueString;
86+
}
87+
88+
public string GetCallArgumentDefinition(WebApiHttpVerb verb)
89+
{
90+
var isFormBody = verb == WebApiHttpVerb.Post || verb == WebApiHttpVerb.Put;
91+
92+
if (!isFormBody)
93+
return string.Empty;
94+
95+
return BodyParameters
96+
.Select(a => a.GetParameterString(false))
97+
.SingleOrDefault();
98+
}
99+
100+
public string GetConstructorParameterNamesList()
101+
{
102+
var constructorParameterNames = GetConstructorParameterMappings()
103+
.Select(p => p.Name);
104+
105+
return string.Join(", ", constructorParameterNames);
106+
}
107+
108+
public string GetConstructorParametersList()
109+
{
110+
var constructorParameterMappings = GetConstructorParameterMappings();
111+
112+
var constructorParameterStrings = constructorParameterMappings
113+
.Select(p => p.String);
114+
115+
var constructorParametersList =
116+
string.Join(", ", constructorParameterStrings);
117+
118+
return constructorParametersList;
119+
}
120+
121+
public IOrderedEnumerable<ConstructorParameterMapping> GetConstructorParameterMappings()
122+
{
123+
var tempConstructorParameters = Method.Parameters
124+
.Select(p => new
125+
{
126+
Parameter = p,
127+
RoutePart = Controller.RouteParts.SingleOrDefault(brp => brp.ParameterName == p.Name)
128+
?? RouteParts.SingleOrDefault(rp => rp.ParameterName == p.Name)
129+
?? QueryStringParameters.SingleOrDefault(qsp => qsp.Name == p.Name)
130+
})
131+
.Where(cp => cp.RoutePart != null)
132+
.ToList();
133+
134+
var constructorParameters = new List<WebApiRoutePart>();
135+
foreach (var tcp in tempConstructorParameters)
136+
{
137+
if (tcp.RoutePart.Parameter == null)
138+
tcp.RoutePart.Parameter = tcp.Parameter;
139+
140+
constructorParameters.Add(tcp.RoutePart);
141+
}
142+
143+
var constructorParameterMappings = constructorParameters
144+
.Select(routePart => new ConstructorParameterMapping
145+
{
146+
IsOptional = TypeService.IsParameterOptional(routePart.Parameter),
147+
TypeMapping = routePart.GetTypeMapping(),
148+
Name = routePart.Parameter.Name,
149+
String = routePart.GetParameterString()
150+
})
151+
.OrderBy(p => p.IsOptional);
152+
153+
return constructorParameterMappings;
154+
}
155+
59156
private void BuildQueryStringAndBodyRouteParts()
60157
{
61158
var actionParameters = Method.Parameters

src/WebApiToTypeScript/WebApi/WebApiRoutePart.cs

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
using Mono.Cecil;
2+
using System;
23
using System.Collections.Generic;
4+
using System.Linq;
5+
using WebApiToTypeScript.Config;
6+
using WebApiToTypeScript.Enums;
7+
using WebApiToTypeScript.Interfaces;
8+
using WebApiToTypeScript.Types;
39

410
namespace WebApiToTypeScript.WebApi
511
{
6-
public class WebApiRoutePart
12+
public class WebApiRoutePart : ServiceAware
713
{
814
public string Name { get; set; }
915
public string ParameterName { get; set; }
@@ -14,5 +20,110 @@ public class WebApiRoutePart
1420

1521
public List<string> CustomAttributes { get; set; }
1622
= new List<string>();
23+
24+
public TypeScriptType GetTypeScriptType()
25+
{
26+
var result = new TypeScriptType();
27+
28+
var parameter = Parameter;
29+
var type = parameter.ParameterType;
30+
var typeName = type.FullName;
31+
32+
var typeMapping = GetTypeMapping();
33+
34+
if (typeMapping != null)
35+
{
36+
var tsTypeName = typeMapping.TypeScriptTypeName;
37+
result.TypeName = tsTypeName;
38+
result.IsPrimitive = TypeService.IsPrimitiveTypeScriptType(result.TypeName);
39+
result.IsEnum = tsTypeName.StartsWith($"{Config.EnumsNamespace}")
40+
|| result.IsPrimitive;
41+
42+
return result;
43+
}
44+
45+
typeName = TypeService.StripNullable(type) ?? typeName;
46+
47+
var collectionType = TypeService.StripCollection(type);
48+
result.IsCollection = collectionType != null;
49+
typeName = collectionType ?? typeName;
50+
51+
var typeDefinition = TypeService.GetTypeDefinition(typeName);
52+
53+
if (typeDefinition?.IsEnum ?? false)
54+
{
55+
if (!Config.GenerateEnums)
56+
{
57+
result.TypeName = "number";
58+
result.IsPrimitive = true;
59+
}
60+
else
61+
{
62+
EnumsService.AddEnum(typeDefinition);
63+
64+
result.TypeName = $"{Config.EnumsNamespace}.{typeDefinition.Name}";
65+
result.IsPrimitive = false;
66+
}
67+
68+
result.IsEnum = true;
69+
return result;
70+
}
71+
72+
var primitiveType = TypeService.GetPrimitiveTypeScriptType(typeName);
73+
74+
if (!string.IsNullOrEmpty(primitiveType))
75+
{
76+
result.TypeName = primitiveType;
77+
result.IsPrimitive = true;
78+
79+
return result;
80+
}
81+
82+
if (!typeDefinition?.IsValueType ?? false)
83+
{
84+
if (!Config.GenerateInterfaces)
85+
{
86+
result.TypeName = $"{WebApiToTypeScript.IHaveQueryParams}";
87+
}
88+
else
89+
{
90+
InterfaceService.AddInterfaceNode(typeDefinition);
91+
92+
result.TypeName = $"{Config.InterfacesNamespace}.{typeDefinition.Name}";
93+
}
94+
95+
return result;
96+
}
97+
98+
throw new NotSupportedException("Maybe it is a generic class, or a yet unsupported collection, or chain thereof?");
99+
}
100+
101+
public string GetParameterString(bool withOptionals = true)
102+
{
103+
var parameter = Parameter;
104+
var isOptional = withOptionals && TypeService.IsParameterOptional(parameter);
105+
var typeScriptType = GetTypeScriptType();
106+
107+
var collectionString = typeScriptType.IsCollection ? "[]" : string.Empty;
108+
109+
return $"{parameter.Name}{(isOptional ? "?" : "")}: {typeScriptType.TypeName}{collectionString}";
110+
}
111+
112+
public TypeMapping GetTypeMapping()
113+
{
114+
if (Parameter == null)
115+
return null;
116+
117+
var typeName = Parameter.ParameterType.FullName;
118+
119+
var typeMapping = Config.TypeMappings
120+
.SingleOrDefault(t => typeName.StartsWith(t.WebApiTypeName)
121+
|| (t.TreatAsAttribute
122+
&& (Helpers.HasCustomAttribute(Parameter, $"{t.WebApiTypeName}Attribute"))
123+
|| (t.TreatAsConstraint
124+
&& Constraints.Any(c => c == Helpers.ToCamelCase(t.WebApiTypeName)))));
125+
126+
return typeMapping;
127+
}
17128
}
18129
}

0 commit comments

Comments
 (0)