[英]Create C# model class for proxy's ASP.NET Web API using T4
I have a WEB API proxy library project that wrap API endpoints. 我有一个包装API端点的WEB API代理库项目。 This library is shipped to C# clients that need to communicate with this Web API project. 该库已交付给需要与此Web API项目进行通信的C#客户端。 I need a T4 script that generate WebAPI response models, in order to avoid manual copy of WebAPI response object type into proxy library project. 我需要一个生成WebAPI响应模型的T4脚本,以避免将WebAPI响应对象类型手动复制到代理库项目中。
You can use the following T4 script. 您可以使用以下T4脚本。 It manage IList, IDictionary, Nullable type and scalar type. 它管理IList,IDictionary,Nullable类型和标量类型。
Assuming you have this response model class returned by your ASP.NET Web API: 假设您的ASP.NET Web API返回了此响应模型类:
Running the T4 script (defined in your proxy project) you will get this definition: 运行T4脚本(在代理项目中定义),您将获得以下定义:
Define this T4 script in your proxy project: 在您的代理项目中定义此T4脚本:
<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ output encoding="utf-8" extension=".cs"#>
<#@ assembly name="$(SolutionDir)xxx.Dis.Services.Endpoints\\bin\\Debug\\xxx.Dis.Services.Endpoints.dll" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="xxx.Dis.Services.Endpoints" #>
<# WriteLine("// ----------------------------------------------------------------------------------------------------------------");
WriteLine("// <auto-generated>");
WriteLine("// This code is automatically generated by tool on " + DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss") + ".");
WriteLine("// Values retrieved from project xxx.Dis.Services.Endpoints");
WriteLine("//");
WriteLine("// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.");
WriteLine("// </auto-generated>");
WriteLine("// ----------------------------------------------------------------------------------------------------------------");
WriteLine("using System;");
WriteLine("using System.Collections.Generic;");
WriteLine("using System.Linq;");
WriteLine("using System.Text;");
WriteLine("");
WriteLine("namespace xxx.Dis.Services.Api.ViewModels");
WriteLine("{");
PushIndent(" ");
// WebAPI's Enum generation
var enumList = from type in typeof(xxx.Dis.Services.Endpoints.ViewModels.Base.BaseViewModel).Assembly.GetTypes() where type.IsEnum select type;
foreach (var type in enumList)
{
WriteLine("public enum " + type.Name);
WriteLine("{");
PushIndent(" ");
foreach (var field in type.GetFields())
{
if (field.Name.Equals("value__")) continue;
WriteLine(field.Name + " = " + field.GetRawConstantValue() + ",");
}
ClearIndent();
PushIndent(" ");
WriteLine("}");
WriteLine("");
}
WriteLine("");
// WebAPI's response Models generation, filtering for all response model implementing a specific base class (in this case named BaseResponseViewModel)
var modelList = from type in typeof(xxx.Dis.Services.Endpoints.ViewModels.Base.BaseViewModel).Assembly.GetTypes() where typeof(xxx.Dis.Services.Endpoints.ViewModels.Base.BaseResponseViewModel).IsAssignableFrom(type) select type;
foreach (var type in modelList)
{
WriteLine("public class " + type.Name);
WriteLine("{");
PushIndent(" ");
foreach (var propertyInfo in type.GetProperties())
{
string propertyTypeString;
var propertyType = propertyInfo.PropertyType;
if (IsList(propertyType))
{
propertyTypeString = PrintList(propertyType);
}
else if (IsDictionary(propertyType))
{
propertyTypeString = PrintDictionary(propertyType);
}
else
{
propertyTypeString = PrintScalar(propertyType);
}
WriteLine(" public " + propertyTypeString + " " + propertyInfo.Name + " { get; set; }");
}
ClearIndent();
PushIndent(" ");
WriteLine("}");
}
ClearIndent();
WriteLine("}");
#>
<#+
public static string PrintScalar(Type type)
{
if (type.IsGenericType)
{
var genericDefionitionName = type.GetGenericTypeDefinition().Name;
if (!string.IsNullOrEmpty(genericDefionitionName) && genericDefionitionName.Contains("Nullable"))
{
var propertyType = type.GetGenericArguments()[0];
return propertyType.Name + "?";
}
}
return type.Name;
}
public static string PrintList(Type type)
{
var argumentType = type.GetGenericArguments()[0];
if (argumentType.IsGenericType && IsNullable(argumentType) == false)
{
if (IsList(argumentType))
{
return "IEnumerable<" + PrintList(argumentType) + ">";
}
if (IsDictionary(argumentType))
{
return "IEnumerable<" + PrintDictionary(argumentType) + ">";
}
}
if (IsNullable(argumentType))
{
return "IEnumerable<" + argumentType.GenericTypeArguments[0].Name + "?>";
}
return "IEnumerable<" + argumentType.Name + ">";
}
public static string PrintDictionary(Type type)
{
var argumentsTypes = type.GetGenericArguments();
// First argument must be not nullable
if (argumentsTypes[0].IsGenericType || IsNullable(argumentsTypes[0])) throw new NotSupportedException("First argument of IDictionary must be not nullable.");
var key = argumentsTypes[0].Name;
if (!argumentsTypes[1].IsGenericType) return "IDictionary<" + key + ", " + argumentsTypes[1].Name + ">";
if (IsNullable(argumentsTypes[1])) return "IDictionary<" + key + ", " + argumentsTypes[1].GenericTypeArguments[0].Name + "?>";
var innerArgumentType = argumentsTypes[1];
if (IsList(innerArgumentType))
{
return "IDictionary<" + key + ", " + PrintList(innerArgumentType) + ">";
}
if (IsDictionary(innerArgumentType))
{
return "IDictionary<" + key + ", " + PrintDictionary(innerArgumentType) + ">";
}
return IsNullable(innerArgumentType)
? "IDictionary<" + key + ", " + innerArgumentType.GenericTypeArguments[0].Name + "?>"
: "IDictionary<" + key + ", " + innerArgumentType.Name + ">";
}
public static bool IsNullable(Type t)
{
var result = t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>);
return result;
}
public static bool IsList(Type t)
{
var result = t.IsGenericType && (t.GetGenericTypeDefinition().IsAssignableFrom(typeof(IList<>)) || t.GetGenericTypeDefinition().IsAssignableFrom(typeof(List<>)));
return result;
}
public static bool IsDictionary(Type t)
{
var result = t.IsGenericType && (t.GetGenericTypeDefinition().IsAssignableFrom(typeof(IDictionary<,>)) || t.GetGenericTypeDefinition().IsAssignableFrom(typeof(Dictionary<,>)));
return result;
}
#>
Enjoy! 请享用!
ASP.NET Web API Client Generators may be more handy, less overhead than T4 templates during SDLC. 与SDLC期间的T4模板相比, ASP.NET Web API客户端生成器可能更方便,开销更少。
While programmers generally use WebApiClientGen to generate TypeScript client API codes with jQuery or Angular2+, this project also provides POCO2TS.exe, a command line program that generates TypsScript interfaces from POCO classes. 尽管程序员通常使用WebApiClientGen通过jQuery或Angular2 +生成TypeScript客户端API代码,但该项目还提供了POCO2TS.exe,这是一种命令行程序,可从POCO类生成TypsScript接口。 You may use either Poco2ts.exe or the poco2ts component to integrate the code generation with your build pipeline. 您可以使用Poco2ts.exe或poco2ts组件将代码生成与构建管道集成在一起。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.