public string GetCode(MetadataTypes metadata, IRequest request)
{
var namespaces = Config.GetDefaultNamespaces(metadata);
metadata.RemoveIgnoredTypesForNet(Config);
if (!Config.ExcludeNamespace)
{
if (Config.GlobalNamespace == null)
{
metadata.Types.Each(x => namespaces.Add(x.Namespace));
metadata.Operations.Each(x => {
namespaces.Add(x.Request.Namespace);
if (x.Response != null)
namespaces.Add(x.Response.Namespace);
});
}
else
{
namespaces.Add(Config.GlobalNamespace);
}
}
Func<string,string> defaultValue = k =>
request.QueryString[k].IsNullOrEmpty() ? "//" : "";
var sbInner = StringBuilderCache.Allocate();
var sb = new StringBuilderWrapper(sbInner);
sb.AppendLine("/* Options:");
sb.AppendLine("Date: {0}".Fmt(DateTime.Now.ToString("s").Replace("T"," ")));
sb.AppendLine("Version: {0}".Fmt(Env.ServiceStackVersion));
sb.AppendLine("Tip: {0}".Fmt(HelpMessages.NativeTypesDtoOptionsTip.Fmt("//")));
sb.AppendLine("BaseUrl: {0}".Fmt(Config.BaseUrl));
sb.AppendLine();
sb.AppendLine("{0}GlobalNamespace: {1}".Fmt(defaultValue("GlobalNamespace"), Config.GlobalNamespace));
sb.AppendLine("{0}MakePartial: {1}".Fmt(defaultValue("MakePartial"), Config.MakePartial));
sb.AppendLine("{0}MakeVirtual: {1}".Fmt(defaultValue("MakeVirtual"), Config.MakeVirtual));
sb.AppendLine("{0}MakeInternal: {1}".Fmt(defaultValue("MakeInternal"), Config.MakeInternal));
sb.AppendLine("{0}MakeDataContractsExtensible: {1}".Fmt(defaultValue("MakeDataContractsExtensible"), Config.MakeDataContractsExtensible));
sb.AppendLine("{0}AddReturnMarker: {1}".Fmt(defaultValue("AddReturnMarker"), Config.AddReturnMarker));
sb.AppendLine("{0}AddDescriptionAsComments: {1}".Fmt(defaultValue("AddDescriptionAsComments"), Config.AddDescriptionAsComments));
sb.AppendLine("{0}AddDataContractAttributes: {1}".Fmt(defaultValue("AddDataContractAttributes"), Config.AddDataContractAttributes));
sb.AppendLine("{0}AddIndexesToDataMembers: {1}".Fmt(defaultValue("AddIndexesToDataMembers"), Config.AddIndexesToDataMembers));
sb.AppendLine("{0}AddGeneratedCodeAttributes: {1}".Fmt(defaultValue("AddGeneratedCodeAttributes"), Config.AddGeneratedCodeAttributes));
sb.AppendLine("{0}AddResponseStatus: {1}".Fmt(defaultValue("AddResponseStatus"), Config.AddResponseStatus));
sb.AppendLine("{0}AddImplicitVersion: {1}".Fmt(defaultValue("AddImplicitVersion"), Config.AddImplicitVersion));
sb.AppendLine("{0}InitializeCollections: {1}".Fmt(defaultValue("InitializeCollections"), Config.InitializeCollections));
sb.AppendLine("{0}ExportValueTypes: {1}".Fmt(defaultValue("ExportValueTypes"), Config.ExportValueTypes));
sb.AppendLine("{0}IncludeTypes: {1}".Fmt(defaultValue("IncludeTypes"), Config.IncludeTypes.Safe().ToArray().Join(",")));
sb.AppendLine("{0}ExcludeTypes: {1}".Fmt(defaultValue("ExcludeTypes"), Config.ExcludeTypes.Safe().ToArray().Join(",")));
sb.AppendLine("{0}AddNamespaces: {1}".Fmt(defaultValue("AddNamespaces"), Config.AddNamespaces.Safe().ToArray().Join(",")));
sb.AppendLine("{0}AddDefaultXmlNamespace: {1}".Fmt(defaultValue("AddDefaultXmlNamespace"), Config.AddDefaultXmlNamespace));
sb.AppendLine("*/");
sb.AppendLine();
namespaces.Where(x => !string.IsNullOrEmpty(x))
.Each(x => sb.AppendLine($"using {x};"));
if (Config.AddGeneratedCodeAttributes)
sb.AppendLine("using System.CodeDom.Compiler;");
if (Config.AddDataContractAttributes
&& Config.AddDefaultXmlNamespace != null)
{
sb.AppendLine();
namespaces.Where(x => !Config.DefaultNamespaces.Contains(x)).ToList()
.ForEach(x => sb.AppendLine(
$"[assembly: ContractNamespace(\"{Config.AddDefaultXmlNamespace}\", ClrNamespace=\"{x}\")]"));
}
sb.AppendLine();
string lastNS = null;
var existingTypes = new HashSet<string>();
var requestTypes = metadata.Operations.Select(x => x.Request).ToHashSet();
var requestTypesMap = metadata.Operations.ToSafeDictionary(x => x.Request);
var responseTypes = metadata.Operations
.Where(x => x.Response != null)
.Select(x => x.Response).ToHashSet();
var types = metadata.Types.ToHashSet();
allTypes = new List<MetadataType>();
allTypes.AddRange(requestTypes);
allTypes.AddRange(responseTypes);
allTypes.AddRange(types);
allTypes = FilterTypes(allTypes);
var orderedTypes = allTypes
.OrderBy(x => x.Namespace)
.ThenBy(x => x.Name);
foreach (var type in orderedTypes)
{
var fullTypeName = type.GetFullName();
if (requestTypes.Contains(type))
{
if (!existingTypes.Contains(fullTypeName))
{
MetadataType response = null;
MetadataOperationType operation;
if (requestTypesMap.TryGetValue(type, out operation))
{
response = operation.Response;
}
lastNS = AppendType(ref sb, type, lastNS, allTypes,
new CreateTypeOptions
{
ImplementsFn = () =>
{
if (!Config.AddReturnMarker
&& !type.ReturnVoidMarker
&& type.ReturnMarkerTypeName == null)
return null;
if (type.ReturnVoidMarker)
return "IReturnVoid";
if (type.ReturnMarkerTypeName != null)
return Type("IReturn`1", new[] { Type(type.ReturnMarkerTypeName) });
return response != null
? Type("IReturn`1", new[] { Type(response.Name, response.GenericArgs) })
: null;
},
IsRequest = true,
});
existingTypes.Add(fullTypeName);
}
}
else if (responseTypes.Contains(type))
{
if (!existingTypes.Contains(fullTypeName)
&& !Config.IgnoreTypesInNamespaces.Contains(type.Namespace))
{
lastNS = AppendType(ref sb, type, lastNS, allTypes,
new CreateTypeOptions { IsResponse = true, });
existingTypes.Add(fullTypeName);
}
}
else if (types.Contains(type) && !existingTypes.Contains(fullTypeName))
{
lastNS = AppendType(ref sb, type, lastNS, allTypes,
new CreateTypeOptions { IsType = true });
existingTypes.Add(fullTypeName);
}
}
if (lastNS != null)
sb.AppendLine("}");
sb.AppendLine();
return StringBuilderCache.ReturnAndFree(sbInner);
}