ky-programming / generator Goto Github PK
View Code? Open in Web Editor NEWType Generator: No framework. No magic. Just code. 100% debuggable.
Home Page: https://generator.ky-programming.de
License: MIT License
Type Generator: No framework. No magic. Just code. 100% debuggable.
Home Page: https://generator.ky-programming.de
License: MIT License
Seems like the generator actually isn't able to handle the Route
-Attribute properly e.g.
[HttpGet, Route("strings/{mystring}/test")]
public string[] GetStrings(string mystring)
{
return new List<string>().ToArray();
}
will be generated to:
public getStrings(mystring: string, httpOptions: {} = undefined): Observable<String[]> {
let subject = new Subject<String[]>();
this.http.get<String[]>(this.serviceUrl + "/api/v1/test?mystring=" + this.convertAny(mystring), httpOptions).subscribe((result) => {
subject.next(result);
subject.complete();
}, (error) => subject.error(error));
return subject;
}
where mystring suddently becomes a parameter instead beeing part of the route.
Hey Kai, first of all many thanks for providing such a nice c# to typescript generator. During use, I noticed that interfaces, applied to a specific class, are consequently ignored during export / generation. Is this the intended behaviour or maybe a feature for an upcoming release?
Thanks and greets!
Hey Kai, I figured out a bit of a special case, where the conversion to typescript seems to be lacking.
I'm creating a generic type
public class GenericType<T>
{
public int Value1 { get; set; }
public T GenericValue { get; set; }
}
which will be used in a list with another custom type
public class InnerCustomType
{
public int CustomValue1 { get; set; }
}
in the following exported class
public class ExportedType
{
public List<GenericType<InnerCustomType>> Listing { get; set; }
}
this will be exported as:
// ------------------------------------------------------------------------------
// <auto-generated>
// This code was generated with KY.Generator 2.7.1.0
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
// ------------------------------------------------------------------------------
// tslint:disable
import { GenericType } from "./generic-type";
import { InnerCustomType } from "./inner-custom-type";
export class ExportedType {
public listing: GenericType[];
public constructor(init: Partial<ExportedType> = undefined) {
Object.assign(this, init);
}
}
Where the GenericType doesn't get resolved correctly.
What do you think - is this a quite too exotic scenario?
Seems like the 8.1 version is missing my beloved GenerateAngularIndex
attribute and the [KY.Generator.GenerateIndex(OutputLanguage.TypeScript,...
doesn't seem to be the right replacement. Am I missing out something?
I've just tested out the controller export feature and came across some weird generation behaviour:
Controller Endpoint:
[HttpGet, Route("string")]
public string[] GetStrings()
{
return new List<string>().ToArray();
}
will be generated with a corrupt import definition: string[]
// ------------------------------------------------------------------------------
// <auto-generated>
// This code was generated with KY.Generator 5.0.1.0
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
// ------------------------------------------------------------------------------
// tslint:disable
import { String[] } from "../api-models/string";
...
public getStrings(httpOptions: {} = undefined): Observable<String[]> {
let subject = new Subject<String[]>();
this.http.get<String[]>(this.serviceUrl + "/api/v1/modelling", httpOptions).subscribe((result) => {
subject.next(result);
subject.complete();
}, (error) => subject.error(error));
return subject;
}
Hey Kai, again thanks for the effort you put on this project - I've just upgraded some projects to the new 4.3 release in order to test your enhancements. Unfortunately for me it seems like there is something broken in the ´´´AngularModelWriter´´´. When changing from 4.2 to 4.3 our builds fail with the following exception:
Error: System.InvalidOperationException occurred. No matching constructor found. Provide default constructor or bind all required parameter types AngularModelWriter
I extracted the logs
System.InvalidOperationException occured
No matching constructor found. Provide default constructor or bind all required parameter types AngularModelWriter
at KY.Core.Dependency.DependencyResolver.Create(Type type, Object[] arguments)
at KY.Core.Dependency.DependencyResolver.Create[T](Object[] arguments)
at KY.Generator.Angular.Commands.AngularModelCommand.Generate(CommandConfiguration configuration, IOutput& output)
at KY.Generator.Command.CommandRunner.Run(IEnumerable`1 configurations, IOutput output)
at KY.Generator.Reflection.Commands.RunByAttributeCommand.Generate(CommandConfiguration configuration, IOutput& output)
at KY.Generator.Command.CommandRunner.<>c__DisplayClass2_0.<Run>b__1(IGeneratorCommand x)
at System.Linq.Enumerable.SelectListIterator`2.ToList()
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at KY.Generator.Command.CommandRunner.Run(CommandConfiguration configuration, IOutput output)
at KY.Generator.Generator.Run()
Does this probably relate to the a missing non parameterized constructor in https://github.com/KY-Programming/generator/blob/5053e3cd5ec70fd23d52613c103258772ccd18a3/Angular/Writers/AngularModelWriter.cs?
Add // tslint:disable
It probably makes sense to also allow the user to set the default http options for the entire api service along with the serviceUrl, rather than having to set them individually for each method that is generated. The default http options then may be merged on each api call. What do you think?
Currently if an SSL certificate error occurs the watchdog waits until the timeout is reached. Maybe it will be better to ignore SSL certificate errors
Hey Kai, we just realized a minor bug during generation of our api endpoints - seems like the generator isn't able to handle custom [Produces("CUSTOM_TYPE")] attributes. Is it a bug, or a feature?
Hey Kai, still a pleasure to use your generator - will the next update also support the the array datatype for custom type definitions? Currently custom typed (FooType) properties marked as array are exported kind of inconsistent:
public class FooClass {
public string[] fooArray1 { get; set; }
public FooType[] fooArray2 { get; set; }
public List<FooListType> fooList { get; set; }
}
currently gets exported as
import { FooType[] } from "./foo-type[]";
import { FooListType } from "./foo-list-type";
export class FooClass {
public fooArray1: string[];
public fooArray2: FooType[];
public fooList: FooListType[];
}
Thanks and regards
Joachim
Seems like the generator is happily adding the CancellationToken from the Route to the export. Is there any way to prevent / exclude?
Hey Kai, seems like I discovered bit of an edge case bug in the ApiController service generator ;-D
It only happens when I'm trying to put a parameter on every endpoint route for a specific controller.... If I move the parameter to every endpoint route, the generator builds the correct routes.
[Route("api/devices/{deviceUid}")]
[GenerateAngularService(Generator.GeneratorServiceOutputPath, Generator.GeneratorModelPath, "{0}ApiService")]
[GenerateIgnoreGeneric(typeof(Response<>))]
public class DeviceController : ControllerBase
....
Any endpoint on this controller will be generated to something like:
this.http.get<boolean>(this.serviceUrl + "/api/devices/{deviceUid}/data" + "?deviceUid=" + this.convertAny(deviceUid), httpOptions).subscribe((result) => {...
which correctly should be:
this.http.get<boolean>(this.serviceUrl + "/api/devices/" + deviceUid + "/data", httpOptions).subscribe((result) => {
without the additional {deviceUid}
Hey Kai, seems like the default IActionResult type for the service generation isn't parsed correctly:
[HttpGet("value")]
public IActionResult GetValue()
{
return this.Ok();
}
will be generated as:
public getValue(httpOptions: {} = undefined): Observable<IActionResult> {
let subject = new Subject<IActionResult>();
this.http.get<IActionResult>(this.serviceUrl + "/api/v1/system/value", httpOptions).subscribe(result => {
const model: IActionResult = result === null || result === undefined ? undefined : **new IActionResult(result);**
subject.next(model);
subject.complete();
}, error => subject.error(error));
return subject;
}
which will lead to TS2693: 'IActionResult' only refers to a type, but is being used as a value here.
==> new IActionResult(result);
You might want to get your hands dirty with a quick fix? ;-)
Hey Kai, I think I discovered another bordercase regarding the signalr service generation.
I have enabled autoreconnect as option during generation.
[KY.Generator.GenerateWithRetry(true, 100, 100, 1000, 5000)]
On my component I call Connect() which will fail due to the targeting service isn't running.
In this case, the signalR service correctly tries to reconnect for infinite times.
Now if I call the Disconnect() method, the service keeps trying to reestablish a connection.
this.isClosed = false;
this.connection = this.connection ? this.connection : new ReplaySubject<HubConnection>(1);
let hubConnection: HubConnection = new HubConnectionBuilder().withUrl(this.serviceUrl).build();
let startConnection: () => Observable<void> = () => {
this.statusSubject.next(ConnectionStatus.connecting);
let subject = new Subject<void>();
hubConnection.start().then(() => {
subject.next();
subject.complete();
this.statusSubject.next(ConnectionStatus.connected);
}).catch((error) => {
this.statusSubject.next(ConnectionStatus.disconnected);
let timeout: number = this.timeouts[trial];
trial++;
timeout = timeout || this.timeouts[this.timeouts.length - 1] || 0;
setTimeout(() => startConnection().subscribe(() => {
subject.next();
subject.complete();
}, (innerError) => subject.error(innerError)), timeout);
});
return subject;
};
Probably U should add the IsClosed check to the retry setTimeout handler, to check whether the connection has been already closed by the user?
Possible solution:
}).catch((error) => {
this.statusSubject.next(ConnectionStatus.disconnected);
//----------------------------------------
if (this.isClosed) {
return;
}
//----------------------------------------
let timeout: number = this.timeouts[trial];
trial++;
timeout = timeout || this.timeouts[this.timeouts.length - 1] || 0;
setTimeout(() => startConnection().subscribe(() => {
subject.next();
subject.complete();
}, (innerError) => subject.error(innerError)), timeout);
});
Hey Kai, thanks for the great updates - I wonder if there is any way to export constants aswell?
for example:
public class MyConstantsRegister {
public const string Constant1 = "my constant 1";
public const string Constant2 = "my constant 2";
...
}
Currently this is not possible, due to you are only watching for properties - but maybe there is any workaround?
Probably with an option to specify a default value via Attribute or Fluent language?
public class MyConstantsRegister {
[KY.PropertyDefaultValue("my constant 1")]
public string Constant1 {get;set;}
[KY.PropertyDefaultValue("my constant 2")]
public string Constant2 = "myconstant 2"
...
}
What do you think?
Hey Kai, due to were trying to squeeze out the last 0.5% of your generator, I just stumbled upon an error in the api controller endpoint generation,... which incorrectly trying to parse a DateTime on a SubType in a listing of MainTypes...
import { SubType } from "./sub-type";
export class MainType {
public creationTime: Date;
public itemUid: string;
public itemNumber: number;
public subItem: SubType;
}
export class SubType {
public creationTime: Date;
...
}
public getListing(httpOptions: {} = undefined): Observable<MainType[]> {
let subject = new Subject<MainType[]>();
this.http.get<MainType[]>(this.serviceUrl + "/api/", httpOptions).subscribe((result) => {
if (result) {
// Correctly parses the dateTime of the main type
result.forEach((entry) => entry.creationTime = this.convertToDate(entry.creationTime));
// ################ This is incorrect
if (result.subclass) {
result.subclass.creationTime = this.convertToDate(result.subclass.creationTime);
}
// ######################## and should be something like
result.forEach((entry) => {
if (entry.subclass) {
entry.subclass.creationTime = this.convertToDate(entry.subclass.creationTime);
}
});
// #########################################################################
}
subject.next(result);
subject.complete();
}, (error) => subject.error(error));
return subject;
}
I think this is gonna be a tougher one to fix,.... maybe there is a option to prevent auto convertion of DateTime fileds in certains cases?
Currently there is no possibility to generate a controller supports oData v4.
Seems like generator is struggeling with special cases like "-" in the assembly name duing export. We are using protobuffer with the .net protobuf-net extension ("protobuf-net.dll") in our projects.
During Typescript / angular generation we receive some errors stating that KY.Generator isn't able to lookup the "-net.dll"
file at the target folder, although the correct referred name is protobuf-net.dll
. The process runs perfectly when we manually provide the assembly name in the load
statement of the generator.json config
"load": [
"..\\..\\packages\\protobuf-net.2.4.0\\lib\\netcoreapp2.1\\protobuf-net.dll"
],
Hey Kai, I wonder if I missed the disconnect method on the generated SignalR Services, or maybe I understand anything wrong?
Hey Kai, seems like I found some linux realted issues during generation with 6.6.2 - the generator isn't searching in the correct nuget folders for the specific Assembly.dll
for example: I'm using System.Reactive version 5.0.0 => the nuget package dlls are located in /home/developer/.nuget/packages/system.reactive/5.0.0/lib/net5.0/System.Reactive.dll
if I'm manually copying the related DLL to one of the lookup folders from the log, the build runs perfectly.
Generator output:
26.03.2021 14:31:59.771: Try to find assembly System.Reactive-5.0.0.0...
26.03.2021 14:31:59.771: Assembly searched in: /home/developer/Projects/myProject/sources/bin/Debug/net5.0/System.Reactive.dll
26.03.2021 14:31:59.772: Assembly searched in: /home/developer/.nuget/packages/ky.generator/6.6.2/tools/netstandard2.0/System.Reactive.dll
26.03.2021 14:31:59.772: Assembly searched in: /home/developer/.nuget/packages/ky.generator/6.6.2/tools/netstandard2.0/bin/System.Reactive.dll
26.03.2021 14:31:59.772: Assembly searched in: /home/developer/.nuget/packages/ky.generator/6.6.2/tools/netstandard2.0/bin/Debug/System.Reactive.dll
26.03.2021 14:31:59.772: Assembly searched in: /home/developer/.nuget/packages/ky.generator/6.6.2/tools/netstandard2.0/bin/Release/System.Reactive.dll
26.03.2021 14:31:59.772: Assembly searched in: /home/developer/Projects/myProject/sources/System.Reactive.dll
26.03.2021 14:31:59.772: Assembly searched in: /home/developer/Projects/myProject/sources/bin/System.Reactive.dll
26.03.2021 14:31:59.772: Assembly searched in: /home/developer/Projects/myProject/sources/bin/Debug/net5.0/System.Reactive.dll
26.03.2021 14:31:59.773: Assembly searched in: /home/developer/Projects/myProject/sources/bin/Debug/System.Reactive.dll
26.03.2021 14:31:59.773: Assembly searched in: /home/developer/Projects/myProject/sources/bin/Release/net5.0/System.Reactive.dll
26.03.2021 14:31:59.773: Assembly searched in: /home/developer/Projects/myProject/sources/bin/Release/System.Reactive.dll
26.03.2021 14:31:59.773: Assembly searched in: /home/developer/.nuget/packages/ky.generator/6.6.2/tools/net5.0/System.Reactive.dll
26.03.2021 14:31:59.773: Assembly searched in: /usr/share/dotnet/shared/Microsoft.AspNetCore.App/5.0.3/System.Reactive.dll
26.03.2021 14:31:59.773: Assembly searched in: /usr/share/dotnet/shared/Microsoft.NETCore.App/5.0.3/System.Reactive.dll
26.03.2021 14:31:59.775: Assembly System.Reactive not found
26.03.2021 14:31:59.777: Try to find assembly System.Reactive-5.0.0.0...
26.03.2021 14:31:59.777: Assembly searched in: /home/developer/Projects/myProject/sources/bin/Debug/net5.0/System.Reactive.dll
26.03.2021 14:31:59.777: Assembly searched in: /home/developer/.nuget/packages/ky.generator/6.6.2/tools/netstandard2.0/System.Reactive.dll
26.03.2021 14:31:59.777: Assembly searched in: /home/developer/.nuget/packages/ky.generator/6.6.2/tools/netstandard2.0/bin/System.Reactive.dll
26.03.2021 14:31:59.778: Assembly searched in: /home/developer/.nuget/packages/ky.generator/6.6.2/tools/netstandard2.0/bin/Debug/System.Reactive.dll
26.03.2021 14:31:59.778: Assembly searched in: /home/developer/.nuget/packages/ky.generator/6.6.2/tools/netstandard2.0/bin/Release/System.Reactive.dll
26.03.2021 14:31:59.778: Assembly searched in: /home/developer/Projects/myProject/sources/System.Reactive.dll
26.03.2021 14:31:59.778: Assembly searched in: /home/developer/Projects/myProject/sources/bin/System.Reactive.dll
26.03.2021 14:31:59.778: Assembly searched in: /home/developer/Projects/myProject/sources/bin/Debug/net5.0/System.Reactive.dll
26.03.2021 14:31:59.778: Assembly searched in: /home/developer/Projects/myProject/sources/bin/Debug/System.Reactive.dll
26.03.2021 14:31:59.778: Assembly searched in: /home/developer/Projects/myProject/sources/bin/Release/net5.0/System.Reactive.dll
26.03.2021 14:31:59.778: Assembly searched in: /home/developer/Projects/myProject/sources/bin/Release/System.Reactive.dll
26.03.2021 14:31:59.779: Assembly searched in: /home/developer/.nuget/packages/ky.generator/6.6.2/tools/net5.0/System.Reactive.dll
26.03.2021 14:31:59.779: Assembly searched in: /usr/share/dotnet/shared/Microsoft.AspNetCore.App/5.0.3/System.Reactive.dll
26.03.2021 14:31:59.779: Assembly searched in: /usr/share/dotnet/shared/Microsoft.NETCore.App/5.0.3/System.Reactive.dll
26.03.2021 14:31:59.779: Assembly System.Reactive not found
26.03.2021 14:31:59.780: Unable to load one or more of the requested types.
Could not load file or assembly 'System.Reactive, Version=5.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263'. The system cannot find the file specified.
Could not load file or assembly 'System.Reactive, Version=5.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263'. The system cannot find the file specified.
at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
at System.Reflection.RuntimeModule.GetTypes()
at System.Reflection.Assembly.GetTypes()
at KY.Generator.Helpers.TypeHelper.GetTypes(Assembly assembly)
26.03.2021 14:31:59.786: Could not load file or assembly 'System.Reactive, Version=5.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263'. The system cannot find the file specified.
As you can see, generator isn't even considering to look in /home/developer/.nuget/packages/system.reactive/5.0.0/lib/net5.0/System.Reactive.dll
is there any tweak I'm missing out?
Hey Kai, seems like the generated SignalR HubServices is breaking when I'm calling the disconnect method on an unconnected connection. In this case the connection property is 'undefined' and the code breaks at this.connection.pipe(take(1)).subscribe((hubConnection) => {
Hot fix could be:
// Close an active connection to the hub.
// If the service is reconnecting/sleeping the connection attempt will be canceled
public disconnect(): void {
this.isClosed = true;
this.connection?.pipe(take(1)).subscribe((hubConnection) => {
hubConnection.stop().then(() => {
this.statusSubject.next(ConnectionStatus.disconnected);
});
});
}
Hey Kai - first of all, congrats to that gorgeous new version 5 you've just released.
There is only one bugfix away from beeing perfect ;-) I just figured out that the generator is struggeling having multiple build definitions targeting different output folders.
My setup contains 2 classes which are targeting two output folders:
[KY.Generator.GenerateAngularModel("..\\..\\..\\my-site\\module1\\api-models")]
public class GeneratorModule1
{
public SubClass1 MySubclass1{ get; set; }
public SubClass2 MySubclass2{ get; set; }
public SubClass3 MySubclass3{ get; set; }
}
[KY.Generator.GenerateAngularModel("..\\..\\..\\my-site\\module2\\api-models")]
public class GeneratorModule2
{
public SubClass4 MySubclass4{ get; set; }
public SubClass5 MySubclass5{ get; set; }
public SubClass6 MySubclass6{ get; set; }
}
It seems like generator is mixing up both definitions and generates all files in both target folders.
Can you confirm that behaviour or have i misconfigured something?
Thanks and greetings!
Hey Kai, I'm missing out the quite useful SkipSelf operator which was available in the old Generator.json configuration - Is there a way to configure it in the new 5.0 Version?
Hey Kai,
first of all: thanks for the magnificent support! I'm referring the issue you have fixed in your last update #8; It seems like the complex scenarios are now working like charm but in my case, its probably struggeling with some base types:
I'm reusing that generic type of #8
public class GenericType<T>
{
public int Value1 { get; set; }
public T GenericValue { get; set; }
}
but this time I'm feeding it a double-Value as Input:
public class ExportedType
{
public GenericType<double> MyType { get; set; }
}
As a result, the GenericType class gets perfectly generated, but in the Exported type the T is not getting resolved:
import { GenericType } from "./generic-type";
export class ExportedType {
public myType: GenericType<>;
public constructor(init: Partial<ExportedType> = undefined) {
Object.assign(this, init);
}
}
Hey Kai, I just stumbled upon the following article of good and bad practices regarding enum type definitions: https://basarat.gitbook.io/typescript/styleguide#enum
What do you think? Currently the generator is exporting as camelCase and I noticed that everywhere else I normally prefer the PascalCase.
I've just discovered the [KY.Generator.Reflection.GenerateIgnore]
attribute which is perfectly usable to ignore certain classes from the generation process. I wonder if there is also an attribute which enables us to ignore certain properties from generation - like NewtonsoftJson does provide with [JsonIgnore]
.
It would be awesome if you can extend the attributes, hence this would save us a lot of extra work wrapping out the unwanted properties.
Thanks and regards!
I think it would be a great extension to make the generator ignore some custom return types of the controllers.
In my case our angular HttpInterceptor
is handling some HttpHeader data from the CustomResponse
and then only throughputs the inner TestData
Object ... the service wrapper for the endpoint therefore must ignore the CustomResponse
type.
[HttpGet, Route("testendpoint")]
public CustomResponse<TestData> GetTestData()
{
return this.GetTestData();
}
Like you already ignore the Task
-type in:
Hey Kai, seems like I just stumbled over a bit of a special issue. In order to run some of our services on 32bit systems I need to switch the build configuration to x86 during build / publish... Unfortunately the Generator is crashing with a build error when trying to load the target specific built assemblies.
Is there a way to support x64 and x86 projects, or maybe switch off the Generator for specific build or publish configurations?
Another small improvement would be to allow users to configure the loglevel for the HubConnectionBuilder.
Like:
public logLevel = LogLevel.Error;
which than can be inserted at the connect() method:
let hubConnection: HubConnection = new HubConnectionBuilder().configureLogging(this.logLevel).withUrl(this.serviceUrl).build();
What do you think?
Hey Kai, first of all thanks for the update to .net 5 and the included fixes for the build target configuration of linux development environments.
Unfortunately I'm still struggeling with the "Error: Command ... not found" exception during build.
Seems like the rest is working like charm - also path resolution:
08:42:16.885: MsBuild trace mode activated
08:42:16.907: KY-Generator v5.5.0.0
08:42:16.908: Current Directory: /home/joachim/Projects/my-project
08:42:16.908: Log Directory: /home/joachim/.nuget/packages/ky.generator/5.5.0/tools/netcoreapp3.0/Logs
08:42:16.918: Try to find assembly System.Reflection.MetadataLoadContext...
08:42:16.922: Assembly found in: /home/joachim/.nuget/packages/ky.generator/5.5.0/tools/netstandard2.0/System.Reflection.MetadataLoadContext.dll
08:42:16.922: Try to find assembly Newtonsoft.Json...
08:42:16.923: Assembly found in: /home/joachim/.nuget/packages/ky.generator/5.5.0/tools/netstandard2.0/Newtonsoft.Json.dll
08:42:16.987: Core-5.5.0.0 module loaded
08:42:17.042: EntityFramework-5.5.0.0 module loaded
08:42:17.042: TypeScript-5.5.0.0 module loaded
08:42:17.042: Watchdog-5.5.0.0 module loaded
08:42:17.042: Csharp-5.5.0.0 module loaded
08:42:17.042: Angular-5.5.0.0 module loaded
08:42:17.042: Tsql-5.5.0.0 module loaded
08:42:17.042: Reflection-5.5.0.0 module loaded
08:42:17.042: OData-5.5.0.0 module loaded
08:42:17.043: Json-5.5.0.0 module loaded
08:42:17.043: OpenApi-5.5.0.0 module loaded
08:42:17.043: AspDotNet-5.5.0.0 module loaded
08:42:17.046: Parse command /home/joachim/Projects/my-project/src/generator.json
08:42:17.054: Error occurred. Command '/home/joachim/Projects/my-project/src/generator.json' not found
Error: Command '/home/joachim/Projects/my-project/src/generator.json' not found
08:42:17.054: Error occurred. See our Documentation: https://generator.ky-programming.de/
Error: See our Documentation: https://generator.ky-programming.de/
By the way, this is my build query:
dotnet /home/joachim/.nuget/packages/ky.generator/5.5.0/build//../tools/netcoreapp3.0/KY.Generator.dll "/home/joachim/Projects/my-project/src/generator.json" -output="/home/joachim/Projects/my-project/src/" -assembly="/home/joachim/Projects/my-project/src/target/debug/my-projectservice.dll" -platform="linux" msbuild beforeBuild
I also recognized a small typo in the build path generation, which doesn't matter on linux:
ky.generator/5.5.0/build//../tool
=> ky.generator/5.5.0/build/../tool
(Doubled //)
Hey Kai, finally I found another edge case, which is probably not handled during a run of the ApiController generation process. I just stumbled upon the option to inject services directly on a specific route using the [FromServices]-Attribute.
Example:
[Route("api/[controller]")]
[ApiController]
public class SecurityController : ControllerBase
{
[HttpGet]
public ActionResult<bool> Get([FromServices] ISecurityService
securityService, string userId, string password)
{
return securityService.Validate(userId, password);
}
//Other methods
}
In this case, the complete Controller gets ignored during build, even if there is only one route using the attribute.
Are you able to reproduce this behaviour?
Hey Kai, still tweaking on the limits of your fantastic generator - I'm facing the scenario where I'm nesting the exported class within the class itself, which leads to an unnecessary import of the nested class:
Exported file: my-class.ts
import { MyClass } from "./my-class";
export class MyClass {
public children: MyClass[];
}
error TS2395: Individual declarations in merged declaration 'MyClass ' must be all exported or all local.
Regards and keep up the great work!
Joachim
Seems like there is still something wrong with the controller generation on POST Endpoints - I receive a typeload exception during export : KY.Generator.targets(37, 5): Error: System.TypeLoadException occurred. Could not load type 'Microsoft.AspNetCore.Mvc.ModelBinding.IConfigureEmptyBodyBehavior' from assembly 'Microsoft.AspNetCore.Mvc.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.
... this seems somehow to be related to the [FromBody] Attribute => If I remove the Attribute the generator runs, unfortunately the endpoint doesn't work in this case ;)
Full log attached:
Could not load type 'Microsoft.AspNetCore.Mvc.ModelBinding.IConfigureEmptyBodyBehavior' from assembly 'Microsoft.AspNetCore.Mvc.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.
at System.ModuleHandle.ResolveTypeHandleInternal(RuntimeModule module, Int32 typeToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
at System.Reflection.RuntimeModule.ResolveType(Int32 metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
at System.Reflection.CustomAttribute.FilterCustomAttributeRecord(MetadataToken caCtorToken, MetadataImport& scope, RuntimeModule decoratedModule, MetadataToken decoratedToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, ListBuilder`1& derivedAttributes, RuntimeType& attributeType, IRuntimeMethodInfo& ctorWithParameters, Boolean& isVarArg)
at System.Reflection.CustomAttribute.AddCustomAttributes(ListBuilder`1& attributes, RuntimeModule decoratedModule, Int32 decoratedMetadataToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, ListBuilder`1 derivedAttributes)
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType)
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeParameterInfo parameter, RuntimeType caType)
at System.Reflection.RuntimeParameterInfo.GetCustomAttributes(Type attributeType, Boolean inherit)
at System.Attribute.InternalParamGetCustomAttributes(ParameterInfo param, Type type, Boolean inherit)
at System.Attribute.GetCustomAttributes(ParameterInfo element, Boolean inherit)
at System.Reflection.CustomAttributeExtensions.GetCustomAttributes(ParameterInfo element)
at KY.Generator.AspDotNet.Readers.AspDotNetControllerReader.IsFromBodyParameter(ParameterInfo parameter)
at KY.Generator.AspDotNet.Readers.AspDotNetControllerReader.Read(AspDotNetReadConfiguration configuration, List`1 transferObjects)
at KY.Generator.AspDotNet.Commands.AspDotNetReadControllerCommand.Run(IOutput output)
at KY.Generator.Command.CommandRunner.Run(IEnumerable`1 commands, IOutput output)
at KY.Generator.Reflection.Commands.AttributesCommand.Run(IOutput output)
at KY.Generator.Command.CommandRunner.Run(IGeneratorCommand command, IOutput output)
at KY.Generator.Generator.Run()
Hey Kai, I just stumbled upon another signalR service related issues... If I trigger a disconnect and finally reconnect again, it seems like there is already a subscription on the connection which surveils the connection state:
public disconnect(): void {
this.isClosed = true;
this.connection.subscribe((hubConnection) => {
hubConnection.stop().then(() => {
this.statusSubject.next(ConnectionStatus.disconnected);
});
});
}
Is there a take(1) or an unsubscribe missing?
In my case on every reconnect, the status$ Observable is firing a "connecting" and several "disconnected" status messages (one for each previous disconnect".
Solution for my case:
public disconnect(): void {
this.isClosed = true;
this.connection.pipe(take(1)).subscribe((hubConnection) => {
hubConnection.stop().then(() => {
this.statusSubject.next(ConnectionStatus.disconnected);
});
});
}
like:
Hey Kai, hope you done well over the holiday season - I just reviewed your last Generator Version 6.2.0 and recognized the return of an already fixed bug during api service generation. Seems like the [FromBody] parameters are parsed incorrect and are transfered to inline query parameters on the API route:
e.g.
[HttpPost("endpoint/post-request")]
public async Task<Response> HandlePost([FromBody] PostParameter postParameter)
{
...
}
==>
public handlePost(postParameter: PostParameter, httpOptions: {} = undefined): Observable<Response> {
let subject = new Subject<Response>();
this.http.post<Response>(this.serviceUrl + "/api/v1/endpoint/post-request" + "?postParameter=" + this.convertAny(postParameter), httpOptions).subscribe((result) => {
subject.next(result);
subject.complete();
}, (error) => subject.error(error));
return subject;
}
Hey Kai, I'm currently playing along with different publish configurations
Seems like the build and publish runs perfectly on x64 / Any build configurations. Unfortunately if I provide the -r
flag during publish in order to force x86 build -r win-x86
the generator doesn't seem to run the correct generator from ky.generator\6.2.1\tools\net5.0-x86
- instead the default ky.generator\6.2.1\tools\net5.0
is called, which can't load x86 assemblies for some reason.
Is this an error or as intended by design?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.