Skip to content

Commit 28cb674

Browse files
committed
Refactor NativeTypesFeature
1 parent 1bda14e commit 28cb674

4 files changed

Lines changed: 99 additions & 76 deletions

File tree

src/ServiceStack/NativeTypes/CSharp/CSharpGenerator.cs

Lines changed: 65 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -73,73 +73,84 @@ public string GetCode(MetadataTypes metadata)
7373
string lastNS = null;
7474

7575
var existingOps = new HashSet<string>();
76-
sb.AppendLine("#region Operations");
77-
sb.AppendLine();
78-
foreach (var operation in metadata.Operations
79-
.OrderBy(x => x.Request.Namespace)
80-
.ThenBy(x => x.Request.Name))
76+
77+
var requestTypes = metadata.Operations.Select(x => x.Request).ToHashSet();
78+
var requestTypesMap = metadata.Operations.ToSafeDictionary(x => x.Request);
79+
var responseTypes = metadata.Operations
80+
.Where(x => x.Response != null)
81+
.Select(x => x.Response).ToHashSet();
82+
var types = metadata.Types.ToHashSet();
83+
84+
var allTypes = new List<MetadataType>();
85+
allTypes.AddRange(requestTypes);
86+
allTypes.AddRange(responseTypes);
87+
allTypes.AddRange(types);
88+
var orderedTypes = allTypes
89+
.OrderBy(x => x.Namespace)
90+
.ThenBy(x => x.Name);
91+
92+
foreach (var type in orderedTypes)
8193
{
82-
var request = operation.Request;
83-
var response = operation.Response;
84-
if (!existingOps.Contains(request.GetFullName()))
94+
var fullTypeName = type.GetFullName();
95+
if (requestTypes.Contains(type))
8596
{
86-
lastNS = AppendType(ref sb, request, lastNS,
87-
new CreateTypeOptions
97+
if (!existingOps.Contains(fullTypeName))
98+
{
99+
MetadataType response = null;
100+
MetadataOperationType operation;
101+
if (requestTypesMap.TryGetValue(type, out operation))
88102
{
89-
ImplementsFn = () =>
103+
response = operation.Response;
104+
}
105+
106+
lastNS = AppendType(ref sb, type, lastNS,
107+
new CreateTypeOptions
90108
{
91-
if (!Config.AddReturnMarker
92-
&& !request.ReturnVoidMarker
93-
&& request.ReturnMarkerTypeName == null)
94-
return null;
95-
96-
if (request.ReturnVoidMarker)
97-
return "IReturnVoid";
98-
if (request.ReturnMarkerTypeName != null)
99-
return Type("IReturn`1", new[] { Type(request.ReturnMarkerTypeName) });
100-
return response != null
101-
? Type("IReturn`1", new[] { Type(response.Name, response.GenericArgs) })
102-
: null;
103-
},
104-
IsRequest = true,
105-
});
106-
107-
existingOps.Add(request.GetFullName());
109+
ImplementsFn = () =>
110+
{
111+
if (!Config.AddReturnMarker
112+
&& !type.ReturnVoidMarker
113+
&& type.ReturnMarkerTypeName == null)
114+
return null;
115+
116+
if (type.ReturnVoidMarker)
117+
return "IReturnVoid";
118+
if (type.ReturnMarkerTypeName != null)
119+
return Type("IReturn`1", new[] { Type(type.ReturnMarkerTypeName) });
120+
return response != null
121+
? Type("IReturn`1", new[] { Type(type.Name, type.GenericArgs) })
122+
: null;
123+
},
124+
IsRequest = true,
125+
});
126+
127+
existingOps.Add(fullTypeName);
128+
}
108129
}
109-
if (response != null && !existingOps.Contains(response.GetFullName())
110-
&& !Config.IgnoreTypesInNamespaces.Contains(response.Namespace))
130+
else if (responseTypes.Contains(type))
111131
{
112-
lastNS = AppendType(ref sb, response, lastNS,
113-
new CreateTypeOptions
114-
{
115-
IsResponse = true,
116-
});
132+
if (!existingOps.Contains(fullTypeName)
133+
&& !Config.IgnoreTypesInNamespaces.Contains(type.Namespace))
134+
{
135+
lastNS = AppendType(ref sb, type, lastNS,
136+
new CreateTypeOptions
137+
{
138+
IsResponse = true,
139+
});
117140

118-
existingOps.Add(response.GetFullName());
141+
existingOps.Add(fullTypeName);
142+
}
143+
}
144+
else if (types.Contains(type) && !existingOps.Contains(fullTypeName))
145+
{
146+
lastNS = AppendType(ref sb, type, lastNS,
147+
new CreateTypeOptions { IsType = true });
119148
}
120149
}
121-
if (lastNS != null)
122-
sb.AppendLine("}");
123-
sb.AppendLine();
124-
sb.AppendLine("#endregion");
125-
126-
sb.AppendLine();
127-
sb.AppendLine();
128150

129-
lastNS = null;
130-
sb.AppendLine("#region Types");
131-
sb.AppendLine();
132-
foreach (var type in metadata.Types
133-
.OrderBy(x => x.Namespace)
134-
.ThenBy(x => x.Name))
135-
{
136-
lastNS = AppendType(ref sb, type, lastNS,
137-
new CreateTypeOptions { IsType = true });
138-
}
139151
if (lastNS != null)
140152
sb.AppendLine("}");
141153
sb.AppendLine();
142-
sb.AppendLine("#endregion");
143154

144155
return sb.ToString();
145156
}

src/ServiceStack/NativeTypes/NativeTypesMetadata.cs

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -130,35 +130,39 @@ public MetadataTypes GetMetadataTypes(IRequest req)
130130
var considered = new HashSet<Type>(opTypes);
131131
var queue = new Queue<Type>(opTypes);
132132

133+
Func<Type, bool> ignoreTypeFn = t =>
134+
t == null
135+
|| considered.Contains(t)
136+
|| skipTypes.Contains(t)
137+
|| ignoreNamespaces.Contains(t.Namespace);
138+
139+
Action<Type> registerTypeFn = t => {
140+
considered.Add(t);
141+
queue.Enqueue(t);
142+
if (t.IsUserType())
143+
metadata.Types.Add(ToType(t));
144+
};
145+
133146
while (queue.Count > 0)
134147
{
135148
var type = queue.Dequeue();
136-
foreach (var pi in type.GetSerializableProperties())
149+
foreach (var pi in type.GetSerializableProperties()
150+
.Where(pi => !ignoreTypeFn(pi.PropertyType)))
137151
{
138-
if (pi.PropertyType.IsUserType())
139-
{
140-
if (considered.Contains(pi.PropertyType))
141-
continue;
142-
if (skipTypes.Contains(pi.PropertyType))
143-
continue;
144-
if (ignoreNamespaces.Contains(pi.PropertyType.Namespace))
145-
continue;
146-
147-
considered.Add(pi.PropertyType);
148-
queue.Enqueue(pi.PropertyType);
149-
metadata.Types.Add(ToType(pi.PropertyType));
150-
}
152+
registerTypeFn(pi.PropertyType);
151153
}
152154

153-
if (type.BaseType != null
154-
&& type.BaseType.IsUserType()
155-
&& !considered.Contains(type.BaseType)
156-
&& !skipTypes.Contains(type.BaseType)
157-
&& !ignoreNamespaces.Contains(type.BaseType.Namespace))
155+
if (!ignoreTypeFn(type.BaseType))
156+
{
157+
registerTypeFn(type.BaseType);
158+
}
159+
160+
if (!type.IsGenericType()) continue;
161+
162+
var args = type.GetGenericArguments();
163+
foreach (var arg in args.Where(arg => !ignoreTypeFn(arg)))
158164
{
159-
considered.Add(type.BaseType);
160-
queue.Enqueue(type.BaseType);
161-
metadata.Types.Add(ToType(type.BaseType));
165+
registerTypeFn(arg);
162166
}
163167
}
164168

src/ServiceStack/NativeTypes/NativeTypesService.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ public class NativeTypesService : Service
4343

4444
public MetadataTypes Any(TypesMetadata request)
4545
{
46+
if (request.BaseUrl == null)
47+
request.BaseUrl = Request.GetBaseUrl();
48+
4649
var typesConfig = NativeTypesMetadata.GetConfig(request);
4750
var metadataTypes = NativeTypesMetadata.GetMetadataTypes(Request, typesConfig);
4851
return metadataTypes;
@@ -51,6 +54,9 @@ public MetadataTypes Any(TypesMetadata request)
5154
[AddHeader(ContentType = MimeTypes.PlainText)]
5255
public object Any(TypesCSharp request)
5356
{
57+
if (request.BaseUrl == null)
58+
request.BaseUrl = Request.GetBaseUrl();
59+
5460
var typesConfig = NativeTypesMetadata.GetConfig(request);
5561
var metadataTypes = NativeTypesMetadata.GetMetadataTypes(Request, typesConfig);
5662
var csharp = new CSharpGenerator(typesConfig).GetCode(metadataTypes);

src/ServiceStack/NativeTypesFeature.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public NativeTypesFeature()
3434
IgnoreTypesInNamespaces = new List<string>
3535
{
3636
"ServiceStack",
37+
"ServiceStack.Auth",
38+
"ServiceStack.Admin",
3739
"ServiceStack.NativeTypes",
3840
"ServiceStack.Api.Swagger",
3941
},

0 commit comments

Comments
 (0)