T4-> Clase C#al modelo de vista eliminada en Typescript
knockout.js typelite (1)
Hice este T4 para hacer que mis contratos de DTO estén disponibles desde JavaScript, tal vez pueda ayudarte
<#@ template debug="true" hostSpecific="true" #>
<#@ output extension=".js" #>
<#@ Assembly Name="System.Core" #>
<#@ Assembly Name="System.Windows.Forms" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="EnvDTE" #>
<#@ include file="../T4/Automation.ttinclude"#><#
var project = VisualStudioHelper.GetProject("MyApp.Core.Contracts");
var contracts = GetSubClasses("MyApp.Core.Contracts.Commands.Command", project)
.Concat(GetSubClasses("MyApp.Core.Contracts.Queries.Query", project));
#>(function(MyApp) {
function buildContract(contract) {
return { type: contract.constructor.type, data: ko.toJSON(contract) };
}
var url = "api/commandQuery";
MyApp.cqrs = {
sendQuery: function(query, callback) {
$.getJSON(url, buildContract(query), callback);
},
sendCommand: function(command) {
MyApp.utils.post(url, buildContract(command));
}
};
<#
foreach(var contract in contracts) {
#>
<#
foreach(var part in BuildNameSpace(contract)) {
#><#= part #>
<#
}
var properties = GetProperties(contract).Select(p => CamelCased(p.Name)).ToList();
var args = string.Join(", ", properties);
#>
window.<#= contract.FullName #> = function(<#= args #>) {<#
foreach(var property in properties) {#>
this.<#= property #> = <#= property #>;<#
}
#>
};
window.<#= contract.FullName #>.type = "<#= contract.FullName #>";
<#
}
#>
})(window.MyApp = window.MyApp || {});
<#+
private static IEnumerable<string> BuildNameSpace(CodeClass @class)
{
return BuildNameSpace(@class.Namespace.Name.Split(''.''), "window", new List<string>());
}
private static IEnumerable<string> BuildNameSpace(IEnumerable<string> @namespace, string parent, List<string> parts)
{
var part = @namespace.FirstOrDefault();
if (part == null) return parts;
var current = string.Format("{0}.{1}", parent, part);
parts.Add(string.Format("{0} = ({0} || {{}});", current));
return BuildNameSpace(@namespace.Skip(1), current, parts);
}
public IEnumerable<CodeClass> GetSubClasses(string baseClass, Project project)
{
return VisualStudioHelper
.CodeModel
.GetAllCodeElementsOfType(project.CodeModel.CodeElements, EnvDTE.vsCMElement.vsCMElementClass, false)
.Cast<CodeClass>()
.Where(c => GetInheritance(c).Any(b => b.FullName == baseClass) && !c.IsAbstract)
.ToList();
}
public IEnumerable<CodeClass> GetInheritance(CodeClass @class)
{
return GetInheritance(@class, new List<CodeClass>());
}
public IEnumerable<CodeClass> GetInheritance(CodeClass @class, List<CodeClass> collection)
{
foreach(CodeClass @base in @class.Bases)
{
collection.Add(@base);
GetInheritance(@base, collection);
}
return collection;
}
public string CamelCased(string pascalCased) {
return pascalCased.Substring(0, 1).ToLower() + pascalCased.Substring(1);
}
public IEnumerable<CodeProperty> GetProperties(CodeClass @class)
{
if (@class == null)
return new List<CodeProperty>();
var baseProperties = GetProperties(@class.Bases.Cast<CodeClass>().FirstOrDefault());
return baseProperties.Concat(@class
.Members
.Cast<CodeElement>()
.Where(ce => ce.Kind == vsCMElement.vsCMElementProperty)
.Cast<CodeProperty>()
.Where(p => p.Access == vsCMAccess.vsCMAccessPublic));
}
#>
Emite un js que se parece a esto
(function(MyApp) {
function buildContract(contract) {
return { type: contract.constructor.type, data: ko.toJSON(contract) };
}
var url = "api/commandQuery";
MyApp.cqrs = {
sendQuery: function(query, callback) {
$.getJSON(url, buildContract(query), callback);
},
sendCommand: function(command) {
MyApp.utils.post(url, buildContract(command));
}
};
window.MyApp = (window.MyApp || {});
window.MyApp.Core = (window.MyApp.Core || {});
window.MyApp.Core.Contracts = (window.MyApp.Core.Contracts || {});
window.MyApp.Core.Contracts.Commands = (window.MyApp.Core.Contracts.Commands || {});
window.MyApp.Core.Contracts.Commands.FooCommand = function(bar) {
this.bar = bar;
};
window.MyApp.Core.Contracts.Commands.FooCommand.type = "MyApp.Core.Contracts.Commands.FooCommand";
})(window.MyApp = window.MyApp || {});
Tenga en cuenta que tiene una dependencia a una plantilla Tangible T4 Editor
<#@ include file="../T4/Automation.ttinclude"#>
Estoy buscando algún tipo de T4 o una forma similar de tomar clases de C # y generar tanto las interfaces para los datos que aparecerán en el cable Y los modelos de vista de una manera fuertemente tipada.
Encontré typelite que funciona bien para las interfaces, pero estoy buscando algo que también maneje los viewmodels (o además de)
Encontré este proyecto que parece excelente: Code Project View Models to JS
Pero, por supuesto, genera javascript y parece no trivial para hackear al escribir incluyendo cosas como enumeraciones, herencia, etc. y hacerlo funcionar con mecanografiado
¿Alguien sabe de un proyecto para hacer esto?
Si no, ¿algún consejo sobre cómo construir esto? No soy experto en T4 y parece bastante impenitrible incluso con herramientas para hacer que la edición de T4 sea menos dañina en Visual Studio.
¡Gracias!