Мне также очень понравился ответ @ citykid, поэтому я расширил его, чтобы сделать целое пространство имен за раз. Просто поместите классы POCO в пространство имен и перестройте шаблоны T4. Мне жаль, что я не знаю, как создавать отдельные файлы для каждого, но это не конец света.
Вам нужно ссылаться на файлы .DLL в верхней части (где вам нужны классы), и вам нужно указать пространства имен. Все строки для редактирования отмечены с помощью ACME. Познай!
<#@ template debug="true" hostSpecific="true" language="C#" #>
<#@ output extension=".ts" #>
<#@ Assembly Name="System.Core.dll" #>
<#@ assembly name="$(TargetDir)YOUR_DLL_NAME_HERE_ACME.dll" #>
<#@ assembly name="$(TargetDir)YOUR_OTHER_DLL_NAME_HERE_ACME.dll" #>
<#@ assembly name="$(TargetDir)YOUR_OTHER_DLL_NAME_HERE_ACME.dll" #>
<#@ assembly name="$(TargetDir)YOUR_OTHER_DLL_NAME_HERE_ACME.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Reflection" #>
<#= Process("My.Very.Special.Namespace.ACME") #>
<#= Process("My.Other.Very.Special.Namespace.ACME") #>
<#= Process("My.Other.Very.Special.Namespace.ACME") #>
<#= Process("My.Other.Very.Special.Namespace.ACME") #>
<#+
List<Type> knownTypes = new List<Type>();
string Process(string nameSpace) {
var allass = AppDomain.CurrentDomain.GetAssemblies();
var ss = "";
foreach (var ass in allass)
{
ss += ProcessAssembly(ass, nameSpace);
}
return ss;
}
string ProcessAssembly(Assembly asm, string nameSpace) {
try {
Type[] types;
try
{
types = asm.GetTypes();
}
catch (ReflectionTypeLoadException e)
{
types = e.Types;
}
var s = "";
foreach (var t in types.Where(t => t != null))
{
try {
if (String.Equals(t.Namespace, nameSpace, StringComparison.Ordinal))
{
s += InterfaceOfType(t);
}
} catch (Exception e)
{
}
}
return s;
}
catch (Exception ee2) {
return "// ERROR LOADING TYPES: " + ee2;
}
}
string InterfaceOfType(Type T)
{
Type t = T;
var sb = new StringBuilder();
sb.AppendFormat("interface {0} {{\r\n", t.Name);
foreach (var mi in GetInterfaceMembers(t))
{
sb.AppendFormat(" {0}: {1};\r\n", this.ToCamelCase(mi.Name), GetTypeName(mi));
}
sb.AppendLine("}");
knownTypes.Add(t);
return sb.ToString();
}
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};\r\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 "boolean";
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},\r\n", name, val);
}
sb.AppendLine("}");
return sb.ToString();
}
#>
Как насчет:
([a-zA-Z]+_?[a-zA-Z]+)*
Это гарантирует, что в любое время, когда подчеркивается символ подчеркивания, он должен быть окружен по крайней мере 1 символом с каждой стороны.
Вам нужно отделить проверку длины символа от шаблона и не забывать привязки, если не добавить неявно:
^(?=.{6,255}$)[a-zA-Z0-9]+(?:_[a-zA-Z0-9]+)*$
Если может быть только одно подчеркивание, замените последний *
на ?
.
Подробности:
^
- начало строки (?=.{6,255}$)
- проверка длины, от 6 до 255 символов другое чем символы разрыва строки [a-zA-Z0-9]+
- 1 или более буквенно-цифровых символов (?:_[a-zA-Z0-9]+)*
- ноль или более вхождений: _
- символ подчеркивания [a-zA-Z0-9]+
- 1 или более буквенно-цифровые символы $
- конец строки.