위의 TypeLite 및 T4TS는 모두 좋아 보였고 TypeLite를 선택하여 지원을 받기 위해 분기했습니다.
- ValueTypes ,
- Nullables
- camelCasing (TypeScript 루트 문서는 낙타를 사용하며 C #과 함께 사용하면 너무 좋습니다)
- 공용 필드 (깨끗하고 읽기 쉬운 POCO를 좋아하고 C # 컴파일러도 쉽게 만들 수 있음)
- 모듈 생성 비활성화
그런 다음 C # 인터페이스가 필요 했고 이제 제 것을 구울 때라고 생각하고 필요한 작업을 수행하는 간단한 T4 스크립트를 작성했습니다. Enums 도 포함됩니다 . 리포지토리가 필요하지 않으며 T4의 100 줄 미만입니다.
사용법
라이브러리, NuGet,이 단순한 T4 파일 만 있으면됩니다. Visual Studio에서 "항목 추가"를 사용하고 T4 템플릿을 선택합니다. 그런 다음 이것을 파일에 붙여 넣습니다. 그 안에 "ACME"가있는 모든 줄을 조정하십시오. 모든 C # 클래스에 대해 한 줄 추가
<#= Interface<Acme.Duck>() #>
순서가 중요합니다. 알려진 모든 유형이 다음 인터페이스에서 사용됩니다. 인터페이스 만 사용하는 경우 파일 확장자는 .d.ts 가 될 수 있습니다. 열거 형의 경우 변수가 인스턴스화되므로 .ts 파일 이 필요합니다 .
사용자 정의
스크립트를 해킹하십시오.
<#@ template debug="true" hostSpecific="true" language="C#" #>
<#@ output extension=".ts" #>
<#@ Assembly Name="System.Core.dll" #>
<#@ assembly name="$(TargetDir)ACME.Core.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Linq" #>
<#= Interface<Acme.Bunny>() #>
<#= Interface<Acme.Duck>() #>
<#= Interface<Acme.Birdy>() #>
<#= Enums<Acme.CarrotGrade>() #>
<#= Interface<Acme.LinkParticle>() #>
<#+
List<Type> knownTypes = new List<Type>();
string Interface<T>()
{
Type t = typeof(T);
var sb = new StringBuilder();
sb.AppendFormat("interface {0} {{\n", t.Name);
foreach (var mi in GetInterfaceMembers(t))
{
sb.AppendFormat(" {0}: {1};\n", this.ToCamelCase(mi.Name), GetTypeName(mi));
}
sb.AppendLine("}");
knownTypes.Add(t);
return sb.ToString();
}
IEnumerable<MemberInfo> GetInterfaceMembers(Type type)
{
return type.GetMembers(BindingFlags.Public | BindingFlags.Instance)
.Where(mi => mi.MemberType == MemberTypes.Field || mi.MemberType == MemberTypes.Property);
}
string ToCamelCase(string s)
{
if (string.IsNullOrEmpty(s)) return s;
if (s.Length < 2) return s.ToLowerInvariant();
return char.ToLowerInvariant(s[0]) + s.Substring(1);
}
string GetTypeName(MemberInfo mi)
{
Type t = (mi is PropertyInfo) ? ((PropertyInfo)mi).PropertyType : ((FieldInfo)mi).FieldType;
return this.GetTypeName(t);
}
string GetTypeName(Type t)
{
if(t.IsPrimitive)
{
if (t == typeof(bool)) return "bool";
if (t == typeof(char)) return "string";
return "number";
}
if (t == typeof(decimal)) return "number";
if (t == typeof(string)) return "string";
if (t.IsArray)
{
var at = t.GetElementType();
return this.GetTypeName(at) + "[]";
}
if(typeof (System.Collections.IEnumerable).IsAssignableFrom(t))
{
var collectionType = t.GetGenericArguments()[0]; // all my enumerables are typed, so there is a generic argument
return GetTypeName(collectionType) + "[]";
}
if (Nullable.GetUnderlyingType(t) != null)
{
return this.GetTypeName(Nullable.GetUnderlyingType(t));
}
if(t.IsEnum) return "number";
if(knownTypes.Contains(t)) return t.Name;
return "any";
}
string Enums<T>() // Enums<>, since Enum<> is not allowed.
{
Type t = typeof(T);
var sb = new StringBuilder();
int[] values = (int[])Enum.GetValues(t);
sb.AppendLine("var " + t.Name + " = {");
foreach(var val in values)
{
var name = Enum.GetName(typeof(T), val);
sb.AppendFormat("{0}: {1},\n", name, val);
}
sb.AppendLine("}");
return sb.ToString();
}
#>
스크립트의 다음 단계는 MVC JsonController 클래스에서 서비스 인터페이스를 만드는 것입니다.