Создайте класс модели C # для ASP.NET Web API прокси, используя T4 - PullRequest
0 голосов
/ 19 мая 2018

У меня есть проект библиотеки прокси WEB API, который оборачивает конечные точки API.Эта библиотека поставляется клиентам C #, которым необходимо взаимодействовать с этим проектом веб-API.Мне нужен сценарий T4, который генерирует модели ответов WebAPI, чтобы избежать ручного копирования типа объекта ответа WebAPI в проект библиотеки прокси.

Ответы [ 2 ]

0 голосов
/ 29 января 2019

Генераторы клиентов веб-API ASP.NET могут быть более удобными, с меньшими затратами, чем шаблоны T4 во время SDLC.

Хотя программисты обычно используют WebApiClientGen для генерации кодов API-клиентов TypeScript с помощью jQuery или Angular2 +этот проект также предоставляет POCO2TS.exe, программу командной строки, которая генерирует интерфейсы TypsScript из классов POCO.Вы можете использовать Poco2ts.exe или компонент poco2ts для интеграции генерации кода с конвейером сборки.

0 голосов
/ 19 мая 2018

Вы можете использовать следующий T4 скрипт.Он управляет IList, IDictionary, типом Nullable и скалярным типом.

Предполагается, что у вас есть этот класс модели ответов, возвращаемый веб-API ASP.NET:

Web API response model type

Запустив сценарий T4 (определенный в вашем прокси-проекте), вы получите следующее определение:

T4 model class generated type

Определитьэтот 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;
    }
#>

Наслаждайтесь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...