W projekcie Webowym z bogatą logiką FrontEndową zawsze w pewnym momencie stajemy przed problemem synchronizacji klas, które mamy w C# z tymi po stronie FE. Jednym z ułatwień jest korzystanie z TypeScript, który udostępnia silne typowanie po stronie FE. Ciągle jednak może być tak, że klasa w C# rozjedzie się z klasą w TypeScript (np. po refaktoringu).
TypeLITE is an utility, that generates TypeScript definitions from .NET classes. It supports all major features of the current TypeScript specification, including modules and inheritance.
TypeLITE generuje C# => TypeScript. Oczywiście tylko definicje właściwości/pól, ick implementacja nie miałaby sensu.
C#:
public class Person { public string Name { get; set; } public List<address> Addresses { get; set; } } public class Employee : Person { public decimal Salary { get; set; } } public class Address { public string Street { get; set; } }
TypeScript:
interface Person { Name: string; Addresses: Address[]; } interface Employee extends Person { Salary: number; } interface Address { Street: string; }
Poniżej opiszę przykład z mojego aktualnego projektu. W trakcie implementacji pojawiło się kilka problemów.
//... <# var ts = TypeScript.Definitions() .For<KMorcinek.Examples.UserDto>() .For<KMorcinek.Examples.Features.ListAdultUsersQuery>() //...
Nie musiałem wskazywać każdej klasy, wystarczy że podałem te „ostateczne”. Gdy UserDto posiada AddressDto to AddressDto również zostanie wygenerowane.
<#@ template debug="false" hostspecific="True" language="C#" #> <#@ assembly name="$(TargetDir)TypeLite.dll" #> <#@ assembly name="$(TargetDir)TypeLite.Net4.dll" #> <#@ assembly name="$(TargetDir)$(TargetFileName)" #> // means current WebApp project <#@ assembly name="$(TargetDir)YourProject.Domain.dll" #> <#@ assembly name="$(TargetDir)YourProject.Application.dll" #>
<# var ts = TypeScript.Definitions() //... .WithMemberFormatter(identifier => Char.ToLower(identifier.Name[0]) + identifier.Name.Substring(1) );
podejście dosyć proste (zmienia tylko pierwszą literę), ale działa. Jeśli chcesz aby „VAT” zostało zmienione na „VAT” zamiast „vAT” to trzeba chyba podpiąć kod podobny do JsonNetSerializera.
<# var ts = TypeScript.Definitions() //... .WithModuleNameFormatter(module => { return module.Name == "System" ? "System" : "YouApplicationName"; })
Dla Guid’ów (w namespace System) był System, dla pozostałych „YouApplicationName”. Nie chcę się bawić ze zbyt długimi namespace’ami.
Narzędzie TypeLITE potrzebuje do prawidłowego działania zbudowanych dll’ek projektów, z których pobiera klasy/modele.
Problem #1:
właściwość
Rozwiązanie:
git checkout -- *.Net4.d.ts
wracamy do poprzedniej wersji wygenerowanego pliku, teraz FE się builduje prawidłowoProblem #2:
W przypadku dodania nowej klasy do C# i dodania do niej ścieżki w pliku TypeLite.Net4.tt, i nie przebudowanu całej solucji przed regenerowaniem aktualnego TypeScriptu znowu może pojawić się się problem z brakiem definicji w plikach TypeLite.Net4.d.ts oraz Enums.ts.
Rozwiązanie:
Rozwiązanie dokładnie takie samo jak opisane w Problemie #1.
Jak tak o tym piszę to widzę że „Net4.” jest zbyt często powtarzane i prawdopodobnie mogę to usunąć.
Miejsce na improvement:
będę wdzięczny gdyby ktoś fajnie opisał jak debugować to coś 🙂
Pingback: dotnetomaniak.pl