Skip to content

Commit bfe4db8

Browse files
committed
refactor: improve FlatBufferEx architecture and reliability
- Implement service-based architecture with DI - Add centralized configuration management - Improve error handling and validation - Add XML documentation and code standards - Fix template rendering and file handling - Update build system and dependencies - Add proper cleanup of temporary files
1 parent 23b73f8 commit bfe4db8

15 files changed

Lines changed: 1030 additions & 168 deletions

Configuration/AppConfiguration.cs

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
using System.ComponentModel.DataAnnotations;
2+
3+
namespace FlatBufferEx.Configuration
4+
{
5+
/// <summary>
6+
/// Application configuration class that holds all settings for the FlatBuffer code generator
7+
/// </summary>
8+
public class AppConfiguration
9+
{
10+
/// <summary>
11+
/// Input directory path containing .fbs schema files
12+
/// </summary>
13+
public string InputPath { get; set; } = string.Empty;
14+
15+
/// <summary>
16+
/// Target languages for code generation (e.g., "c++|c#")
17+
/// </summary>
18+
public string Languages { get; set; } = "c#";
19+
20+
/// <summary>
21+
/// Output directory path for generated code
22+
/// </summary>
23+
public string OutputPath { get; set; } = "output";
24+
25+
/// <summary>
26+
/// Include directory path for additional schema files
27+
/// </summary>
28+
public string IncludePath { get; set; } = string.Empty;
29+
30+
/// <summary>
31+
/// Supported languages
32+
/// </summary>
33+
public static readonly HashSet<string> SupportedLanguages = new() { "c++", "c#" };
34+
35+
/// <summary>
36+
/// Default FlatBuffer compiler download URL
37+
/// </summary>
38+
public string FlatBufferCompilerUrl { get; set; } = "https://github.com/google/flatbuffers/releases/download/v25.2.10/Windows.flatc.binary.zip";
39+
40+
/// <summary>
41+
/// Temporary directory for raw FlatBuffer files
42+
/// </summary>
43+
public string TempDirectory { get; set; } = "raw";
44+
45+
/// <summary>
46+
/// FlatBuffer compiler directory
47+
/// </summary>
48+
public string CompilerDirectory { get; set; } = "flatbuffer";
49+
50+
/// <summary>
51+
/// Template directory path
52+
/// </summary>
53+
public string TemplateDirectory { get; set; } = "Template";
54+
55+
/// <summary>
56+
/// Gets the parsed target languages
57+
/// </summary>
58+
public IEnumerable<string> GetTargetLanguages()
59+
{
60+
return Languages
61+
.Split('|')
62+
.Select(x => x.Trim().ToLower())
63+
.Where(x => !string.IsNullOrEmpty(x))
64+
.Distinct();
65+
}
66+
67+
/// <summary>
68+
/// Validates the configuration and returns validation errors
69+
/// </summary>
70+
/// <param name="errors">Collection of validation errors</param>
71+
/// <returns>True if configuration is valid, false otherwise</returns>
72+
public bool IsValid(out List<string> errors)
73+
{
74+
errors = new List<string>();
75+
76+
// Validate input path
77+
if (string.IsNullOrWhiteSpace(InputPath))
78+
{
79+
errors.Add("Input path is required");
80+
}
81+
else if (!Directory.Exists(InputPath))
82+
{
83+
errors.Add($"Input directory does not exist: {InputPath}");
84+
}
85+
86+
// Validate output path
87+
if (string.IsNullOrWhiteSpace(OutputPath))
88+
{
89+
errors.Add("Output path is required");
90+
}
91+
92+
// Validate languages
93+
if (string.IsNullOrWhiteSpace(Languages))
94+
{
95+
errors.Add("At least one target language must be specified");
96+
}
97+
else
98+
{
99+
var targetLanguages = GetTargetLanguages().ToList();
100+
if (!targetLanguages.Any())
101+
{
102+
errors.Add("No valid target languages specified");
103+
}
104+
105+
var unsupportedLanguages = targetLanguages.Where(lang => !SupportedLanguages.Contains(lang)).ToList();
106+
if (unsupportedLanguages.Any())
107+
{
108+
errors.Add($"Unsupported languages: {string.Join(", ", unsupportedLanguages)}. Supported languages: {string.Join(", ", SupportedLanguages)}");
109+
}
110+
}
111+
112+
// Validate template directory
113+
if (!Directory.Exists(TemplateDirectory))
114+
{
115+
errors.Add($"Template directory does not exist: {TemplateDirectory}");
116+
}
117+
118+
return !errors.Any();
119+
}
120+
121+
/// <summary>
122+
/// Gets the full output path
123+
/// </summary>
124+
public string GetFullOutputPath()
125+
{
126+
return Path.GetFullPath(OutputPath);
127+
}
128+
129+
/// <summary>
130+
/// Gets the language-specific compiler environment name
131+
/// </summary>
132+
/// <param name="language">Target language</param>
133+
/// <returns>Compiler environment name</returns>
134+
public string GetCompilerEnvironment(string language)
135+
{
136+
return language switch
137+
{
138+
"c++" => "cpp",
139+
"c#" => "csharp",
140+
_ => throw new ArgumentException($"Unsupported language: {language}")
141+
};
142+
}
143+
144+
/// <summary>
145+
/// Gets the file extension for the target language
146+
/// </summary>
147+
/// <param name="language">Target language</param>
148+
/// <returns>File extension</returns>
149+
public string GetFileExtension(string language)
150+
{
151+
return language switch
152+
{
153+
"c++" => ".h",
154+
"c#" => ".cs",
155+
_ => throw new ArgumentException($"Unsupported language: {language}")
156+
};
157+
}
158+
}
159+
}

FlatBufferEx.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
<OutputType>Exe</OutputType>
55
<TargetFramework>net8.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>disable</Nullable>
8+
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
9+
<WarningsAsErrors />
10+
<WarningsNotAsErrors>CS0618</WarningsNotAsErrors>
711
</PropertyGroup>
812

913
<ItemGroup>
@@ -17,6 +21,7 @@
1721
<PackageReference Include="NDesk.Options.Core" Version="1.2.8" />
1822
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
1923
<PackageReference Include="Scriban" Version="5.10.0" />
24+
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
2025
</ItemGroup>
2126

2227
<ItemGroup>

Generator.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using FlatBufferEx.Model;
2+
using FlatBufferEx.Services;
23
using Scriban;
34

45
namespace FlatBufferEx
@@ -7,11 +8,12 @@ namespace FlatBufferEx
78
/// Static generator class for creating FlatBuffer schema content
89
/// Generates raw FlatBuffer (.fbs) content for tables and enums using Scriban templates
910
/// </summary>
11+
[Obsolete("Use ITemplateService instead. This class is kept for backward compatibility.")]
1012
public static class Generator
1113
{
1214
// Pre-compiled Scriban templates for generating raw FlatBuffer content
13-
private static readonly Template RawTableTemplate = Template.Parse(File.ReadAllText("Template/raw.table.txt"));
14-
private static readonly Template RawEnumTemplate = Template.Parse(File.ReadAllText("Template/raw.enum.txt"));
15+
private static readonly Lazy<Template> RawTableTemplate = new(() => Template.Parse(File.ReadAllText("Template/raw.table.txt")));
16+
private static readonly Lazy<Template> RawEnumTemplate = new(() => Template.Parse(File.ReadAllText("Template/raw.enum.txt")));
1517

1618
/// <summary>
1719
/// Generates raw FlatBuffer table content using the table template
@@ -29,7 +31,7 @@ public static string RawFlatBufferTableContents(Model.Table table, string lang)
2931
ctx.PushGlobal(obj);
3032

3133
// Render the template with the context
32-
return RawTableTemplate.Render(ctx);
34+
return RawTableTemplate.Value.Render(ctx);
3335
}
3436

3537
/// <summary>
@@ -48,7 +50,7 @@ public static string RawFlatBufferEnumContents(Model.Enum e, string lang)
4850
ctx.PushGlobal(obj);
4951

5052
// Render the template with the context
51-
return RawEnumTemplate.Render(ctx);
53+
return RawEnumTemplate.Value.Render(ctx);
5254
}
5355
}
5456
}

0 commit comments

Comments
 (0)