Open WilfriedRicken opened 6 years ago
Can you provide a sample project which does this generation?
So, basically we scan a given folder for *.json files, and for each file found we call CSharpGenerator. Looks like this one:
private static void Generate(string folder)
{
foreach (var file in Directory.GetFiles(folder, "*.json"))
{
if (Path.GetFileName(file).ToLower() == "project.json")
continue;
if (Path.GetFileName(file).ToLower() == "project.lock.json")
continue;
// Generate class from json schema file
Console.WriteLine($"Generating C# code from schema {file}");
var schema = JsonSchema4.FromFileAsync(file).Result;
var settings = new CSharpGeneratorSettings { Namespace = folder.Replace(Path.DirectorySeparatorChar, '.').Trim('.'), ClassStyle = CSharpClassStyle.Inpc };
settings.TemplateFactory = new PrismTemplateFactory(schema, settings, new[] { typeof(CSharpGeneratorSettings).GetTypeInfo().Assembly });
var generator = new CSharpGenerator(schema, settings);
var fileName = Path.ChangeExtension(file, ".cs");
using (var stream = File.Open(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (var writer = new StreamWriter(stream))
{
Console.WriteLine(fileName);
writer.Write(generator.GenerateFile(Path.GetFileNameWithoutExtension(file)));
}
}
}
foreach (var childFolder in Directory.GetDirectories(folder))
{
Generate(childFolder);
}
}
Any progress? Is there a chance to get this in an official release?
This issue is a big problem for us. Therefore: Could you give me a hint where I can start in the code and I would like to make a proposal how tomsolve it. Thanks!
Instead of using GenerateFile(), try to use GenerateTypes() and collect all artifacts, then filter out duplicates and merge everything into a single CodeArtifactCollection, then merge everything into a single file with generator.GenerateFile(CodeArtifactCollection artifactCollection)
This would result in one large single file I assume? I need exactly the opposite: Every class, enum, ... which is defined in a json schema should be in a single cs-File. What I did now (and what only works half way):
public class MyCSharpGenerator : CSharpGenerator
{
public MyCSharpGenerator(object rootObject)
: base(rootObject)
{
}
public MyCSharpGenerator(object rootObject, CSharpGeneratorSettings settings)
: base(rootObject, settings)
{
}
public MyCSharpGenerator(object rootObject, CSharpGeneratorSettings settings, CSharpTypeResolver resolver)
: base(rootObject, settings, resolver)
{
}
protected override string GenerateFile(CodeArtifactCollection artifactCollection)
{
CodeArtifact[] artifacts = { artifactCollection.Artifacts.Last() };
return base.GenerateFile(new CodeArtifactCollection(artifacts, artifactCollection.ExtensionCode));
}
}
This at least does not produce duplicate classes, however, it has two problems:
Any further idea? I think it would be best to have a switch in CSharpGeneratorSettings to specify whether $ref-included classes should be supressed in code generation and their usage should be the fully qualified type name for that class.
Ok, fixed this problem for us by deriving from CSharpCodeGenerator and modifying the code artifact collection. However, it would be very helpful if CodeArtifact could get a property "OriginalFileName" which contains the name of the JSON schema where it came from. Actually, we use a mix of convention (if there is a file with TypeName.json, then replace code by using statement) and first come, first serve (if there is no such file, the first occurence of a TypeName will be generated, all other occurences will be replaced by using statement). The second approach deals e.g. with enums declared directly at a property, and this one is not exactly what one would expect.
FYI: Multiple file output should be supported: https://github.com/RSuter/NJsonSchema/issues/514
I think it would be best to have a switch in CSharpGeneratorSettings to specify whether $ref-included classes should be supressed in code generation and their usage should be the fully qualified type name for that class.
I think this setting should be possible to add...
We have JSON schema which uses $ref to specify the type of a referenced class in a JSON schema. However, the classes are now emitted more than once. Is it possible to supress this?
Example:
OrderDTO.json:
JobDTO.json:
Generating code for both JSON schema files leads to two generated classes JobDTO.json, one correctly in a file JobDTO.cs, another one as a duplicate in OrderDTO.cs.
One could argue that only OrderDTO.cs is needed, however, better would be to suppress the generation of JobDTO in OrderDTO.cs because the $ref correctly refers to another class in another file. When using $ref more than once including only one file would be not sufficient anymore.
Any idea?