In this Article, we will discuss about sql generation
DatabaseHelper.cs
----------------------------
using System;
using System.Collections.Generic;
using Microsoft.Data.SqlClient;
namespace BoilerplateApiGenerator
{
public static class DatabaseHelper
{
public static List<string> GetDatabases(string connection)
{
using var con = new SqlConnection(connection);
con.Open();
using var cmd = new SqlCommand("SELECT name FROM sys.databases WHERE database_id > 4 ORDER BY name", con);
using var rdr = cmd.ExecuteReader();
var list = new List<string>();
while (rdr.Read()) list.Add(rdr.GetString(0));
return list;
}
public static List<TableSchema> GetTables(string connection, string dbName)
{
var tables = new Dictionary<string, TableSchema>(StringComparer.OrdinalIgnoreCase);
using var con = new SqlConnection($"{connection};Initial Catalog={dbName}");
con.Open();
// Columns
using (var cmd = new SqlCommand(@"
SELECT c.TABLE_NAME, c.COLUMN_NAME, c.DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS c
ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION", con))
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
var t = rdr.GetString(0);
var col = rdr.GetString(1);
var dt = rdr.GetString(2);
if (!tables.TryGetValue(t, out var ts))
{
ts = new TableSchema { Name = t };
tables[t] = ts;
}
ts.Columns.Add(new ColumnSchema { Name = col, DataType = dt });
}
}
// Primary keys
using (var cmd = new SqlCommand(@"
SELECT tc.TABLE_NAME, kcu.COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
ON tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME
AND tc.TABLE_NAME = kcu.TABLE_NAME
WHERE tc.CONSTRAINT_TYPE = 'PRIMARY KEY'
", con))
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
var t = rdr.GetString(0);
var pk = rdr.GetString(1);
if (tables.TryGetValue(t, out var ts))
{
ts.PrimaryKey = pk;
}
}
}
return new List<TableSchema>(tables.Values);
}
}
public class TableSchema
{
public string Name { get; set; } = string.Empty;
public string? PrimaryKey { get; set; }
public List<ColumnSchema> Columns { get; set; } = new();
}
public class ColumnSchema
{
public string Name { get; set; } = string.Empty;
public string DataType { get; set; } = string.Empty;
}
}
GeneratorService.cs
-----------------------------------
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace BoilerplateApiGenerator
{
public class GeneratorService
{
private readonly string _outputDir;
public GeneratorService(string outputDir) => _outputDir = outputDir;
// ---------------------------------------------------------------------
// Main entry point to generate the complete 4-layer project
// ---------------------------------------------------------------------
public void GenerateSolution(
string projectName,
string connString,
string dbName,
List<TableSchema> tables)
{
// string solutionPath = Path.Combine(_outputDir, $"{projectName}.Generated");
string solutionPath = Path.Combine(_outputDir, projectName);
Directory.CreateDirectory(solutionPath);
string nsDomain = $"{projectName}.Domain";
string nsApp = $"{projectName}.Application";
string nsInfra = $"{projectName}.Infrastructure";
string nsApi = $"{projectName}.Api";
// ---------------- DOMAIN ----------------
string domDir = Path.Combine(solutionPath, $"{projectName}.Domain");
Directory.CreateDirectory(Path.Combine(domDir, "Entities"));
Directory.CreateDirectory(Path.Combine(domDir, "Abstractions"));
foreach (var tbl in tables)
{
File.WriteAllText(Path.Combine(domDir, "Entities", $"{tbl.Name}.cs"),
TemplateEngine.GenerateDomainEntity(nsDomain, tbl));
File.WriteAllText(Path.Combine(domDir, "Abstractions", $"I{tbl.Name}Repository.cs"),
TemplateEngine.GenerateDomainRepositoryAbstraction(nsDomain, tbl));
}
File.WriteAllText(Path.Combine(domDir, $"{projectName}.Domain.csproj"),
TemplateEngine.GenerateDomainCsproj());
// ---------------- APPLICATION ----------------
string appDir = Path.Combine(solutionPath, $"{projectName}.Application");
Directory.CreateDirectory(Path.Combine(appDir, "DTOs"));
Directory.CreateDirectory(Path.Combine(appDir, "Interfaces"));
Directory.CreateDirectory(Path.Combine(appDir, "Mapping"));
foreach (var tbl in tables)
{
File.WriteAllText(Path.Combine(appDir, "DTOs", $"{tbl.Name}Dtos.cs"),
TemplateEngine.GenerateApplicationDtos(nsApp, tbl));
File.WriteAllText(Path.Combine(appDir, "Interfaces", $"I{tbl.Name}Service.cs"),
TemplateEngine.GenerateApplicationInterfaces(nsApp, tbl));
}
File.WriteAllText(Path.Combine(appDir, "Mapping", "MappingProfile.cs"),
TemplateEngine.GenerateMappingProfile(nsApp, nsDomain, tables));
File.WriteAllText(Path.Combine(appDir, "DependencyInjection.cs"),
TemplateEngine.GenerateAppDependencyInjection(nsApp));
File.WriteAllText(Path.Combine(appDir, $"{projectName}.Application.csproj"),
TemplateEngine.GenerateApplicationCsproj().Replace("{PROJECT}", projectName));
// ---------------- INFRASTRUCTURE ----------------
string infraDir = Path.Combine(solutionPath, $"{projectName}.Infrastructure");
Directory.CreateDirectory(Path.Combine(infraDir, "Data"));
Directory.CreateDirectory(Path.Combine(infraDir, "Repositories"));
Directory.CreateDirectory(Path.Combine(infraDir, "Services"));
Directory.CreateDirectory(Path.Combine(infraDir, "Identity"));
Directory.CreateDirectory(Path.Combine(infraDir, "Logging"));
File.WriteAllText(Path.Combine(infraDir, "Data", "AppDbContext.cs"),
TemplateEngine.GenerateInfrastructureDbContext(nsInfra, nsDomain, tables));
File.WriteAllText(Path.Combine(infraDir, "Identity", "ApplicationUser.cs"),
TemplateEngine.GenerateIdentityUser(nsInfra));
foreach (var tbl in tables)
{
File.WriteAllText(Path.Combine(infraDir, "Repositories", $"{tbl.Name}Repository.cs"),
TemplateEngine.GenerateInfrastructureRepository(nsInfra, nsDomain, tbl));
File.WriteAllText(Path.Combine(infraDir, "Services", $"{tbl.Name}Service.cs"),
TemplateEngine.GenerateInfrastructureService(nsInfra, nsApp, nsDomain, tbl));
}
// Add Logging Service (Singleton NLog)
File.WriteAllText(Path.Combine(infraDir, "Logging", "LoggingService.cs"),
TemplateEngine.GenerateInfrastructureLoggingService(nsInfra));
// Add DI setup including LoggingService Singleton
File.WriteAllText(Path.Combine(infraDir, "DependencyInjection.cs"),
TemplateEngine.GenerateInfraDependencyInjection(nsInfra, nsDomain, nsApp, tables));
File.WriteAllText(Path.Combine(infraDir, $"{projectName}.Infrastructure.csproj"),
TemplateEngine.GenerateInfrastructureCsproj().Replace("{PROJECT}", projectName));
// ---------------- API ----------------
string apiDir = Path.Combine(solutionPath, $"{projectName}.Api");
Directory.CreateDirectory(Path.Combine(apiDir, "Controllers"));
Directory.CreateDirectory(Path.Combine(apiDir, "Properties"));
Directory.CreateDirectory(Path.Combine(apiDir, "Middleware"));
Directory.CreateDirectory(Path.Combine(apiDir, "Extensions"));
Directory.CreateDirectory(Path.Combine(apiDir, "Models"));
foreach (var tbl in tables)
{
File.WriteAllText(Path.Combine(apiDir, "Controllers", $"{tbl.Name}Controller.cs"),
TemplateEngine.GenerateApiController(nsApi, nsApp, tbl));
}
// Add Global Exception Middleware under API
File.WriteAllText(Path.Combine(apiDir, "Middleware", "GlobalExceptionMiddleware.cs"),
TemplateEngine.GenerateGlobalExceptionMiddleware(nsApi));
// Add Error Response model
File.WriteAllText(Path.Combine(apiDir, "Models", "ErrorResponse.cs"),
TemplateEngine.GenerateErrorResponseModel(nsApi));
// Add Middleware Extension
File.WriteAllText(Path.Combine(apiDir, "Extensions", "ExceptionMiddlewareExtensions.cs"),
TemplateEngine.GenerateExceptionMiddlewareExtension(nsApi));
// Program.cs with app.UseGlobalException()
File.WriteAllText(Path.Combine(apiDir, "Program.cs"),
TemplateEngine.GenerateApiProgramCs(nsApp, nsInfra, nsApi));
// NLog configuration
File.WriteAllText(Path.Combine(apiDir, "nlog.config"),
TemplateEngine.GenerateNLogConfig());
// appsettings.json
File.WriteAllText(Path.Combine(apiDir, "appsettings.json"),
TemplateEngine.GenerateAppSettings(connString, dbName));
// launchSettings.json for auto Swagger
Directory.CreateDirectory(Path.Combine(apiDir, "Properties"));
File.WriteAllText(Path.Combine(apiDir, "Properties", "launchSettings.json"),
TemplateEngine.GenerateLaunchSettings(projectName));
// API .csproj
File.WriteAllText(Path.Combine(apiDir, $"{projectName}.Api.csproj"),
TemplateEngine.GenerateApiCsproj(projectName));
// Create the Solution File
CreateSolutionFile(solutionPath, projectName);
// Write README Summary
File.WriteAllText(Path.Combine(solutionPath, "README_Generated.txt"),
BuildSummary(projectName, solutionPath, tables));
}
// ---------------------------------------------------------------------
// Solution Summary
// ---------------------------------------------------------------------
private static string BuildSummary(string projectName, string solutionPath, List<TableSchema> tables)
{
var sb = new StringBuilder();
sb.AppendLine($"=== {projectName} Boilerplate Generated ===");
sb.AppendLine($"Location: {solutionPath}");
sb.AppendLine();
sb.AppendLine("Tables Processed:");
foreach (var t in tables)
sb.AppendLine($" - {t.Name} ({t.Columns.Count} columns)");
sb.AppendLine();
sb.AppendLine("Projects:");
sb.AppendLine($" • {projectName}.Domain");
sb.AppendLine($" • {projectName}.Application");
sb.AppendLine($" • {projectName}.Infrastructure");
sb.AppendLine($" • {projectName}.Api");
sb.AppendLine();
sb.AppendLine("Includes:");
sb.AppendLine(" NLog Singleton Logger");
sb.AppendLine(" Global Exception Handling Middleware");
sb.AppendLine(" Swagger Auto Launch");
sb.AppendLine(" Full DI Configuration");
sb.AppendLine();
sb.AppendLine("To run:");
sb.AppendLine($" 1. Open {projectName}.sln");
sb.AppendLine($" 2. Set {projectName}.Api as startup project.");
sb.AppendLine(" 3. Run → Swagger UI auto-opens with JWT + GlobalExceptionMiddleware.");
sb.AppendLine();
sb.AppendLine("If you get error in the generated application do the below:");
sb.AppendLine("Add - <PackageReference Include=\"Microsoft.AspNetCore.Authentication.JwtBearer\" Version=\"8.0.0\" /> in in SmartCertify.API\\SmartCertify.API.Infrastructure\\SmartCertify.API.Infrastructure.csproj - ");
sb.AppendLine("change verion number to 5.3.0 for NLog - <PackageReference Include=\"NLog\" Version=\"5.3.0\" />");
sb.AppendLine("Comment the code in(NLog.Config) in Infrastructure - <PackageReference Include = \"NLog.Config\" Version = \"5.0.5\" />");
sb.AppendLine("Generated by BoilerplateApiGenerator");
return sb.ToString();
}
// ---------------------------------------------------------------------
// Create Visual Studio Solution File
// ---------------------------------------------------------------------
private static void CreateSolutionFile(string solutionPath, string projectName)
{
string solutionFile = Path.Combine(solutionPath, $"{projectName}.sln");
var sb = new StringBuilder();
sb.AppendLine("Microsoft Visual Studio Solution File, Format Version 12.00");
sb.AppendLine("# Visual Studio Version 17");
sb.AppendLine("VisualStudioVersion = 17.0.31903.59");
sb.AppendLine("MinimumVisualStudioVersion = 10.0.40219.1");
string[] layers = { "Domain", "Application", "Infrastructure", "Api" };
foreach (var layer in layers)
{
string guid = Guid.NewGuid().ToString("B").ToUpper();
string projPath = $"{projectName}.{layer}\\{projectName}.{layer}.csproj";
sb.AppendLine($"Project(\"{{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}}\") = \"{projectName}.{layer}\", \"{projPath}\", \"{guid}\"");
sb.AppendLine("EndProject");
}
sb.AppendLine("Global");
sb.AppendLine(" GlobalSection(SolutionConfigurationPlatforms) = preSolution");
sb.AppendLine(" Debug|Any CPU = Debug|Any CPU");
sb.AppendLine(" Release|Any CPU = Release|Any CPU");
sb.AppendLine(" EndGlobalSection");
sb.AppendLine(" GlobalSection(SolutionProperties) = preSolution");
sb.AppendLine(" HideSolutionNode = FALSE");
sb.AppendLine(" EndGlobalSection");
sb.AppendLine("EndGlobal");
File.WriteAllText(solutionFile, sb.ToString(), Encoding.UTF8);
}
}
}
MainForm.cs
-------------------------
using System;
using System.IO;
using System.Linq;
using System.Reflection.Emit;
using System.Windows.Forms;
using System.Xml.Linq;
namespace BoilerplateApiGenerator
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void btnLoadDBs_Click(object sender, EventArgs e)
{
try
{
var dbs = DatabaseHelper.GetDatabases(txtConnection.Text);
cmbDatabases.Items.Clear();
foreach (var d in dbs) cmbDatabases.Items.Add(d);
if (dbs.Count > 0) cmbDatabases.SelectedIndex = 0;
MessageBox.Show($"Loaded {dbs.Count} databases.");
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
}
}
private void btnLoadTables_Click(object sender, EventArgs e)
{
try
{
if (cmbDatabases.SelectedItem is null)
{
MessageBox.Show("Please select a database first.");
return;
}
chkTables.Items.Clear();
var tables = DatabaseHelper.GetTables(txtConnection.Text, cmbDatabases.SelectedItem!.ToString()!);
foreach (var t in tables.Select(t => t.Name).Distinct())
chkTables.Items.Add(t, true);
MessageBox.Show("Tables loaded. Select/deselect as needed.");
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
}
}
private void btnBrowse_Click(object sender, EventArgs e)
{
using var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() == DialogResult.OK)
txtOutput.Text = fbd.SelectedPath;
}
private void btnGenerate_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(txtProjectName.Text))
{
MessageBox.Show("Enter a project name (e.g., MyCompany.Api).");
return;
}
if (cmbDatabases.SelectedItem is null)
{
MessageBox.Show("Select a database.");
return;
}
if (string.IsNullOrWhiteSpace(txtOutput.Text) || !Directory.Exists(txtOutput.Text))
{
MessageBox.Show("Choose a valid output folder.");
return;
}
var allTables = DatabaseHelper.GetTables(txtConnection.Text, cmbDatabases.SelectedItem!.ToString()!);
var selected = chkTables.CheckedItems.Cast<string>().ToHashSet(StringComparer.OrdinalIgnoreCase);
var useTables = allTables.Where(t => selected.Contains(t.Name)).ToList();
if (useTables.Count == 0)
{
MessageBox.Show("Please select at least one table.");
return;
}
progressBar1.Visible = true;
btnGenerate.Enabled = false;
try
{
var gen = new GeneratorService(txtOutput.Text);
gen.GenerateSolution(txtProjectName.Text.Trim(), txtConnection.Text, cmbDatabases.SelectedItem!.ToString()!, useTables);
//await gen.GenerateApiAsync(txtProjectName.Text.Trim(), txtConnection.Text, cmbDatabases.SelectedItem!.ToString()!, useTables);
MessageBox.Show("API generated successfully.");
}
catch (Exception ex)
{
MessageBox.Show("Generation failed: " + ex.Message);
}
finally
{
btnGenerate.Enabled = true;
progressBar1.Visible = false;
}
}
}
}
MainForm.Designer.cs
-------------------------------------
namespace BoilerplateApiGenerator
{
partial class MainForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.txtConnection = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.btnLoadDBs = new System.Windows.Forms.Button();
this.cmbDatabases = new System.Windows.Forms.ComboBox();
this.label2 = new System.Windows.Forms.Label();
this.btnLoadTables = new System.Windows.Forms.Button();
this.chkTables = new System.Windows.Forms.CheckedListBox();
this.label3 = new System.Windows.Forms.Label();
this.txtProjectName = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this.txtOutput = new System.Windows.Forms.TextBox();
this.btnBrowse = new System.Windows.Forms.Button();
this.btnGenerate = new System.Windows.Forms.Button();
this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.SuspendLayout();
//
// txtConnection
//
this.txtConnection.Location = new System.Drawing.Point(24, 44);
this.txtConnection.Name = "txtConnection";
this.txtConnection.Size = new System.Drawing.Size(612, 27);
this.txtConnection.TabIndex = 0;
this.txtConnection.Text = "Server=.;Integrated Security=True;TrustServerCertificate=True;";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(24, 20);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(202, 20);
this.label1.TabIndex = 1;
this.label1.Text = "SQL Server connection string";
//
// btnLoadDBs
//
this.btnLoadDBs.Location = new System.Drawing.Point(642, 44);
this.btnLoadDBs.Name = "btnLoadDBs";
this.btnLoadDBs.Size = new System.Drawing.Size(117, 29);
this.btnLoadDBs.TabIndex = 2;
this.btnLoadDBs.Text = "Load DBs";
this.btnLoadDBs.UseVisualStyleBackColor = true;
this.btnLoadDBs.Click += new System.EventHandler(this.btnLoadDBs_Click);
//
// cmbDatabases
//
this.cmbDatabases.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmbDatabases.FormattingEnabled = true;
this.cmbDatabases.Location = new System.Drawing.Point(24, 110);
this.cmbDatabases.Name = "cmbDatabases";
this.cmbDatabases.Size = new System.Drawing.Size(349, 28);
this.cmbDatabases.TabIndex = 3;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(24, 87);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(77, 20);
this.label2.TabIndex = 4;
this.label2.Text = "Database";
//
// btnLoadTables
//
this.btnLoadTables.Location = new System.Drawing.Point(379, 110);
this.btnLoadTables.Name = "btnLoadTables";
this.btnLoadTables.Size = new System.Drawing.Size(118, 29);
this.btnLoadTables.TabIndex = 5;
this.btnLoadTables.Text = "Load Tables";
this.btnLoadTables.UseVisualStyleBackColor = true;
this.btnLoadTables.Click += new System.EventHandler(this.btnLoadTables_Click);
//
// chkTables
//
this.chkTables.CheckOnClick = true;
this.chkTables.FormattingEnabled = true;
this.chkTables.Location = new System.Drawing.Point(24, 170);
this.chkTables.Name = "chkTables";
this.chkTables.Size = new System.Drawing.Size(349, 312);
this.chkTables.TabIndex = 6;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(24, 147);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(56, 20);
this.label3.TabIndex = 7;
this.label3.Text = "Tables";
//
// txtProjectName
//
this.txtProjectName.Location = new System.Drawing.Point(397, 170);
this.txtProjectName.Name = "txtProjectName";
this.txtProjectName.PlaceholderText = "MyCompany.Api";
this.txtProjectName.Size = new System.Drawing.Size(362, 27);
this.txtProjectName.TabIndex = 8;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(397, 147);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(99, 20);
this.label4.TabIndex = 9;
this.label4.Text = "Project name";
//
// txtOutput
//
this.txtOutput.Location = new System.Drawing.Point(397, 226);
this.txtOutput.Name = "txtOutput";
this.txtOutput.ReadOnly = true;
this.txtOutput.Size = new System.Drawing.Size(302, 27);
this.txtOutput.TabIndex = 10;
//
// btnBrowse
//
this.btnBrowse.Location = new System.Drawing.Point(705, 225);
this.btnBrowse.Name = "btnBrowse";
this.btnBrowse.Size = new System.Drawing.Size(54, 29);
this.btnBrowse.TabIndex = 11;
this.btnBrowse.Text = "...";
this.btnBrowse.UseVisualStyleBackColor = true;
this.btnBrowse.Click += new System.EventHandler(this.btnBrowse_Click);
//
// btnGenerate
//
this.btnGenerate.Location = new System.Drawing.Point(397, 275);
this.btnGenerate.Name = "btnGenerate";
this.btnGenerate.Size = new System.Drawing.Size(362, 39);
this.btnGenerate.TabIndex = 12;
this.btnGenerate.Text = "Generate API Boilerplate";
this.btnGenerate.UseVisualStyleBackColor = true;
this.btnGenerate.Click += new System.EventHandler(this.btnGenerate_Click);
//
// progressBar1
//
this.progressBar1.Location = new System.Drawing.Point(397, 333);
this.progressBar1.MarqueeAnimationSpeed = 30;
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(362, 18);
this.progressBar1.Style = System.Windows.Forms.ProgressBarStyle.Marquee;
this.progressBar1.TabIndex = 13;
this.progressBar1.Visible = false;
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(784, 511);
this.Controls.Add(this.progressBar1);
this.Controls.Add(this.btnGenerate);
this.Controls.Add(this.btnBrowse);
this.Controls.Add(this.txtOutput);
this.Controls.Add(this.label4);
this.Controls.Add(this.txtProjectName);
this.Controls.Add(this.label3);
this.Controls.Add(this.chkTables);
this.Controls.Add(this.btnLoadTables);
this.Controls.Add(this.label2);
this.Controls.Add(this.cmbDatabases);
this.Controls.Add(this.btnLoadDBs);
this.Controls.Add(this.label1);
this.Controls.Add(this.txtConnection);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "MainForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Boilerplate API Code Generator (EF Core + Swagger)";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox txtConnection;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button btnLoadDBs;
private System.Windows.Forms.ComboBox cmbDatabases;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Button btnLoadTables;
private System.Windows.Forms.CheckedListBox chkTables;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox txtProjectName;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.TextBox txtOutput;
private System.Windows.Forms.Button btnBrowse;
private System.Windows.Forms.Button btnGenerate;
private System.Windows.Forms.ProgressBar progressBar1;
}
}
Program.cs
--------------------------------------------------
using System;
using System.Windows.Forms;
namespace BoilerplateApiGenerator
{
internal static class Program
{
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
Application.Run(new MainForm());
}
}
}
TemplateEngine.cs
----------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BoilerplateApiGenerator
{
public static class TemplateEngine
{
// ------------------- DOMAIN -------------------
public static string GenerateDomainEntity(string nsDomain, TableSchema tbl)
{
var pkCol = tbl.Columns.FirstOrDefault(c =>
string.Equals(c.Name, tbl.PrimaryKey ?? "Id", StringComparison.OrdinalIgnoreCase))
?? tbl.Columns.First();
var sb = new StringBuilder();
sb.AppendLine("using System;");
sb.AppendLine("using System.ComponentModel.DataAnnotations;");
sb.AppendLine();
sb.AppendLine($"namespace {nsDomain}.Entities;");
sb.AppendLine();
sb.AppendLine($"public class {tbl.Name}");
sb.AppendLine("{");
foreach (var col in tbl.Columns)
{
var type = MapCSharpType(col.DataType);
if (string.Equals(col.Name, pkCol.Name, StringComparison.OrdinalIgnoreCase))
sb.AppendLine(" [Key]");
sb.AppendLine($" public {type} {col.Name} {{ get; set; }}");
}
sb.AppendLine("}");
return sb.ToString();
}
public static string GenerateDomainRepositoryAbstraction(string ns, TableSchema tbl)
{
return $@"using System.Linq;
using System.Threading.Tasks;
using {ns}.Entities;
namespace {ns}.Abstractions;
public interface I{tbl.Name}Repository
{{
Task<{tbl.Name}?> GetAsync(int id);
IQueryable<{tbl.Name}> Query();
Task<{tbl.Name}> AddAsync({tbl.Name} e);
Task UpdateAsync({tbl.Name} e);
Task DeleteAsync({tbl.Name} e);
Task SaveAsync();
}}";
}
public static string GenerateDomainCsproj() =>
@"<Project Sdk=""Microsoft.NET.Sdk"">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>";
// ------------------- APPLICATION -------------------
public static string GenerateApplicationDtos(string ns, TableSchema tbl)
{
var props = string.Join(Environment.NewLine,
tbl.Columns.Select(c => $" public {MapCSharpType(c.DataType)} {c.Name} {{ get; set; }}"));
return $@"namespace {ns}.DTOs;
public class {tbl.Name}ReadDto
{{
{props}
}}
public class {tbl.Name}CreateDto
{{
{props}
}}
public class {tbl.Name}UpdateDto
{{
{props}
}}";
}
public static string GenerateApplicationInterfaces(string ns, TableSchema tbl)
{
return $@"using System.Collections.Generic;
using System.Threading.Tasks;
using {ns}.DTOs;
namespace {ns}.Interfaces;
public interface I{tbl.Name}Service
{{
Task<{tbl.Name}ReadDto?> GetAsync(int id);
Task<IEnumerable<{tbl.Name}ReadDto>> GetAllAsync();
Task<{tbl.Name}ReadDto> CreateAsync({tbl.Name}CreateDto dto);
Task<{tbl.Name}ReadDto?> UpdateAsync(int id, {tbl.Name}UpdateDto dto);
Task<bool> DeleteAsync(int id);
}}";
}
public static string GenerateMappingProfile(string nsApp, string nsDomain, IEnumerable<TableSchema> tables)
{
var sb = new StringBuilder();
sb.AppendLine("using AutoMapper;");
sb.AppendLine($"using {nsApp}.DTOs;");
sb.AppendLine($"using {nsDomain}.Entities;");
sb.AppendLine();
sb.AppendLine($"namespace {nsApp}.Mapping;");
sb.AppendLine("public class MappingProfile : Profile");
sb.AppendLine("{");
sb.AppendLine(" public MappingProfile()");
sb.AppendLine(" {");
foreach (var tbl in tables)
{
sb.AppendLine($" CreateMap<{tbl.Name}, {tbl.Name}ReadDto>();");
sb.AppendLine($" CreateMap<{tbl.Name}CreateDto, {tbl.Name}>();");
sb.AppendLine($" CreateMap<{tbl.Name}UpdateDto, {tbl.Name}>();");
sb.AppendLine($" CreateMap<{tbl.Name}, {tbl.Name}UpdateDto>();");
}
sb.AppendLine(" }");
sb.AppendLine("}");
return sb.ToString();
}
public static string GenerateAppDependencyInjection(string ns)
{
return $@"using Microsoft.Extensions.DependencyInjection;
using AutoMapper;
using System.Reflection;
namespace {ns};
public static class DependencyInjection
{{
public static IServiceCollection AddApplication(this IServiceCollection services)
{{
services.AddAutoMapper(Assembly.GetExecutingAssembly());
return services;
}}
}}";
}
public static string GenerateApplicationCsproj() =>
@"<Project Sdk=""Microsoft.NET.Sdk"">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include=""..\{PROJECT}.Domain\{PROJECT}.Domain.csproj"" />
</ItemGroup>
<ItemGroup>
<PackageReference Include=""AutoMapper.Extensions.Microsoft.DependencyInjection"" Version=""12.0.1"" />
</ItemGroup>
</Project>";
// ------------------- INFRASTRUCTURE -------------------
public static string GenerateInfrastructureCsproj() =>
@"<Project Sdk=""Microsoft.NET.Sdk"">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include=""..\{PROJECT}.Domain\{PROJECT}.Domain.csproj"" />
<ProjectReference Include=""..\{PROJECT}.Application\{PROJECT}.Application.csproj"" />
</ItemGroup>
<ItemGroup>
<PackageReference Include=""Microsoft.EntityFrameworkCore.SqlServer"" Version=""8.0.0"" />
<PackageReference Include=""Microsoft.AspNetCore.Identity.EntityFrameworkCore"" Version=""8.0.0"" />
<PackageReference Include=""Microsoft.AspNetCore.Authentication.JwtBearer"" Version=""8.0.0"" />
<PackageReference Include=""NLog"" Version=""5.3.0"" />
<!--<PackageReference Include=""NLog.Config"" Version=""5.0.5"" /> -->
<PackageReference Include=""NLog.Extensions.Logging"" Version=""5.3.0"" />
</ItemGroup>
</Project>";
public static string GenerateInfraDependencyInjection(string nsInfra, string nsDomain, string nsApp, List<TableSchema> tables)
{
var registrations = new StringBuilder();
// Dynamically register all repositories and services for each table/entity
foreach (var tbl in tables)
{
registrations.AppendLine(
$" services.AddScoped<{nsDomain}.Abstractions.I{tbl.Name}Repository, {nsInfra}.Repositories.{tbl.Name}Repository>();");
registrations.AppendLine(
$" services.AddScoped<{nsApp}.Interfaces.I{tbl.Name}Service, {nsInfra}.Services.{tbl.Name}Service>();");
}
return $@"using System;
using System.Text;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using {nsInfra}.Data;
using {nsInfra}.Identity;
using {nsInfra}.Logging;
using {nsDomain}.Abstractions;
using {nsApp}.Interfaces;
using {nsInfra}.Repositories;
using {nsInfra}.Services;
namespace {nsInfra};
public static class DependencyInjection
{{
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
{{
// ---------------- Database ----------------
services.AddDbContext<AppDbContext>(opt =>
opt.UseSqlServer(configuration.GetConnectionString(""DefaultConnection"")));
// ---------------- Identity ----------------
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<AppDbContext>()
.AddDefaultTokenProviders();
// ---------------- JWT Authentication ----------------
var key = Encoding.UTF8.GetBytes(configuration[""Jwt:Key""]!);
services.AddAuthentication(options =>
{{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}})
.AddJwtBearer(options =>
{{
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidIssuer = configuration[""Jwt:Issuer""],
ValidAudience = configuration[""Jwt:Audience""],
ClockSkew = TimeSpan.FromMinutes(2)
}};
}});
// ---------------- Authorization ----------------
services.AddAuthorization();
// ---------------- Logging (Singleton) ----------------
services.AddSingleton<ILoggingService>(LoggingService.Instance);
// ---------------- Dynamic Service/Repository Registrations ----------------
{registrations}
return services;
}}
}}";
}
public static string GenerateInfrastructureLoggingService(string nsInfra)
{
return $@"using NLog;
using NLog.Config;
using NLog.Targets;
namespace {nsInfra}.Logging;
public interface ILoggingService
{{
void LogInfo(string message);
void LogError(string message, Exception ex);
}}
public sealed class LoggingService : ILoggingService
{{
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
private static readonly Lazy<LoggingService> _instance = new(() => new LoggingService());
public static LoggingService Instance => _instance.Value;
private LoggingService()
{{
var config = new LoggingConfiguration();
var fileTarget = new FileTarget(""logfile"")
{{
FileName = ""logs/logfile.txt"",
Layout = ""${{longdate}} | ${{level:uppercase=true}} | ${{message}} | ${{exception}}""
}};
var consoleTarget = new ConsoleTarget(""logconsole"")
{{
Layout = ""${{longdate}} | ${{level}} | ${{message}}""
}};
config.AddRule(LogLevel.Info, LogLevel.Fatal, consoleTarget);
config.AddRule(LogLevel.Debug, LogLevel.Fatal, fileTarget);
LogManager.Configuration = config;
}}
public void LogInfo(string message) => _logger.Info(message);
public void LogError(string message, Exception ex) => _logger.Error(ex, message);
}}";
}
// ------------------- GLOBAL EXCEPTION -------------------
public static string GenerateGlobalExceptionMiddleware(string nsApi)
{
var nsInfra = nsApi.Replace(".Api", ".Infrastructure");
return $@"using System.Net;
using System.Text.Json;
using Microsoft.AspNetCore.Http;
using {nsApi}.Models;
using {nsInfra}.Logging;
namespace {nsApi}.Middleware;
public class GlobalExceptionMiddleware
{{
private readonly RequestDelegate _next;
private readonly ILoggingService _logger;
public GlobalExceptionMiddleware(RequestDelegate next, ILoggingService logger)
{{
_next = next;
_logger = logger;
}}
public async Task InvokeAsync(HttpContext context)
{{
try
{{
await _next(context);
}}
catch (Exception ex)
{{
_logger.LogError(""Unhandled Exception"", ex);
await HandleExceptionAsync(context, ex);
}}
}}
private static Task HandleExceptionAsync(HttpContext context, Exception ex)
{{
var response = new ErrorResponse
{{
StatusCode = (int)HttpStatusCode.InternalServerError,
Message = ex.Message,
Details = ex.InnerException?.Message
}};
context.Response.ContentType = ""application/json"";
context.Response.StatusCode = response.StatusCode;
return context.Response.WriteAsync(JsonSerializer.Serialize(response));
}}
}}";
}
public static string GenerateErrorResponseModel(string nsApi)
{
return $@"namespace {nsApi}.Models;
public class ErrorResponse
{{
public int StatusCode {{ get; set; }}
public string Message {{ get; set; }} = string.Empty;
public string? Details {{ get; set; }}
}}";
}
public static string GenerateExceptionMiddlewareExtension(string nsApi)
{
return $@"using Microsoft.AspNetCore.Builder;
namespace {nsApi}.Extensions;
public static class ExceptionMiddlewareExtensions
{{
public static IApplicationBuilder UseGlobalException(this IApplicationBuilder app)
{{
app.UseMiddleware<{nsApi}.Middleware.GlobalExceptionMiddleware>();
return app;
}}
}}";
}
// ------------------- NLOG CONFIG -------------------
public static string GenerateNLogConfig()
{
return @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<nlog xmlns=""http://www.nlog-project.org/schemas/NLog.xsd""
xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
autoReload=""true"" throwConfigExceptions=""true"" internalLogLevel=""Off"">
<targets>
<target xsi:type=""File"" name=""logfile"" fileName=""logs/logfile.txt"" layout=""${longdate} | ${level:uppercase=true} | ${logger} | ${message} | ${exception}"" />
<target xsi:type=""Console"" name=""logconsole"" layout=""${longdate} | ${level} | ${message}"" />
</targets>
<rules>
<logger name=""*"" minlevel=""Debug"" writeTo=""logfile"" />
<logger name=""*"" minlevel=""Info"" writeTo=""logconsole"" />
</rules>
</nlog>";
}
// ------------------- SWAGGER AUTO LAUNCH -------------------
public static string GenerateLaunchSettings(string projectName)
{
return $@"{{
""profiles"": {{
""http"": {{
""commandName"": ""Project"",
""dotnetRunMessages"": true,
""launchBrowser"": true,
""launchUrl"": ""swagger"",
""applicationUrl"": ""http://localhost:5000"",
""environmentVariables"": {{
""ASPNETCORE_ENVIRONMENT"": ""Development""
}}
}},
""https"": {{
""commandName"": ""Project"",
""dotnetRunMessages"": true,
""launchBrowser"": true,
""launchUrl"": ""swagger"",
""applicationUrl"": ""https://localhost:5001"",
""environmentVariables"": {{
""ASPNETCORE_ENVIRONMENT"": ""Development""
}}
}}
}}
}}";
}
// ------------------- HELPER -------------------
public static string MapCSharpType(string sqlType)
{
sqlType = sqlType.ToLower();
if (sqlType.Contains("int")) return "int";
if (sqlType.Contains("char") || sqlType.Contains("text")) return "string";
if (sqlType.Contains("date") || sqlType.Contains("time")) return "DateTime";
if (sqlType.Contains("decimal") || sqlType.Contains("numeric")) return "decimal";
if (sqlType.Contains("float") || sqlType.Contains("real")) return "double";
if (sqlType.Contains("bit")) return "bool";
return "string";
}
// ---------------- Infrastructure Repository ----------------
public static string GenerateInfrastructureRepository(string nsInfra, string nsDomain, TableSchema tbl)
{
var entity = tbl.Name;
var pkCol = tbl.Columns.FirstOrDefault(c =>
string.Equals(c.Name, tbl.PrimaryKey ?? "Id", StringComparison.OrdinalIgnoreCase))
?? tbl.Columns.First();
var pkType = MapCSharpType(pkCol.DataType);
return $@"using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using {nsInfra}.Data;
using {nsDomain}.Entities;
using {nsDomain}.Abstractions;
namespace {nsInfra}.Repositories;
public class {entity}Repository : I{entity}Repository
{{
private readonly AppDbContext _db;
public {entity}Repository(AppDbContext db) => _db = db;
public async Task<{entity}?> GetAsync({pkType} id) => await _db.{entity}.FindAsync(id);
public IQueryable<{entity}> Query() => _db.{entity}.AsNoTracking();
public async Task<{entity}> AddAsync({entity} e) {{ _db.{entity}.Add(e); await _db.SaveChangesAsync(); return e; }}
public async Task UpdateAsync({entity} e) {{ _db.{entity}.Update(e); await _db.SaveChangesAsync(); }}
public async Task DeleteAsync({entity} e) {{ _db.{entity}.Remove(e); await _db.SaveChangesAsync(); }}
public async Task SaveAsync() => await _db.SaveChangesAsync();
}}";
}
// ---------------- Infrastructure Service ----------------
public static string GenerateInfrastructureService(string nsInfra, string nsApp, string nsDomain, TableSchema tbl)
{
var entity = tbl.Name;
var pkCol = tbl.Columns.FirstOrDefault(c =>
string.Equals(c.Name, tbl.PrimaryKey ?? "Id", StringComparison.OrdinalIgnoreCase))
?? tbl.Columns.First();
var pkType = MapCSharpType(pkCol.DataType);
return $@"using System.Collections.Generic;
using System.Threading.Tasks;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using Microsoft.EntityFrameworkCore;
using {nsApp}.DTOs;
using {nsApp}.Interfaces;
using {nsDomain}.Entities;
using {nsDomain}.Abstractions;
namespace {nsInfra}.Services;
public class {entity}Service : I{entity}Service
{{
private readonly I{entity}Repository _repo;
private readonly IMapper _mapper;
public {entity}Service(I{entity}Repository repo, IMapper mapper)
{{
_repo = repo;
_mapper = mapper;
}}
public async Task<{entity}ReadDto?> GetAsync({pkType} id)
=> _mapper.Map<{entity}ReadDto?>(await _repo.GetAsync(id));
public async Task<IEnumerable<{entity}ReadDto>> GetAllAsync()
=> await _repo.Query().ProjectTo<{entity}ReadDto>(_mapper.ConfigurationProvider).ToListAsync();
public async Task<{entity}ReadDto> CreateAsync({entity}CreateDto dto)
{{
var e = _mapper.Map<{entity}>(dto);
await _repo.AddAsync(e);
return _mapper.Map<{entity}ReadDto>(e);
}}
public async Task<{entity}ReadDto?> UpdateAsync({pkType} id, {entity}UpdateDto dto)
{{
var e = await _repo.GetAsync(id);
if (e is null) return null;
_mapper.Map(dto, e);
await _repo.SaveAsync();
return _mapper.Map<{entity}ReadDto>(e);
}}
public async Task<bool> DeleteAsync({pkType} id)
{{
var e = await _repo.GetAsync(id);
if (e is null) return false;
await _repo.DeleteAsync(e);
return true;
}}
}}";
}
// ---------------- Infrastructure DbContext ----------------
public static string GenerateInfrastructureDbContext(string nsInfra, string nsDomain, List<TableSchema> tables)
{
var dbSets = string.Join(Environment.NewLine,
tables.Select(t => $" public DbSet<{nsDomain}.Entities.{t.Name}> {t.Name} {{ get; set; }}"));
return $@"using Microsoft.EntityFrameworkCore;
using {nsDomain}.Entities;
namespace {nsInfra}.Data;
public class AppDbContext : DbContext
{{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) {{ }}
{dbSets}
}}";
}
// ---------------- Identity User ----------------
public static string GenerateIdentityUser(string nsInfra)
{
return $@"using Microsoft.AspNetCore.Identity;
namespace {nsInfra}.Identity;
public class ApplicationUser : IdentityUser
{{
}}";
}
// ---------------- AppSettings ----------------
public static string GenerateAppSettings(string connString, string dbName)
{
string safeConn = connString.Replace("\\", "\\\\");
return $@"{{
""ConnectionStrings"": {{
""DefaultConnection"": ""{safeConn};Initial Catalog={dbName};TrustServerCertificate=True""
}},
""Jwt"": {{
""Key"": ""CHANGE_THIS_TO_A_LONG_RANDOM_SECRET_KEY_AT_LEAST_64_CHARS"",
""Issuer"": ""Generated.Api"",
""Audience"": ""Generated.Client"",
""ExpiryMinutes"": 120
}},
""Logging"": {{
""LogLevel"": {{
""Default"": ""Information"",
""Microsoft.AspNetCore"": ""Warning""
}}
}},
""AllowedHosts"": ""*""
}}";
}
// ---------------- API Controller ----------------
public static string GenerateApiController(string nsApi, string nsApp, TableSchema tbl)
{
var entity = tbl.Name;
var pkCol = tbl.Columns.FirstOrDefault(c =>
string.Equals(c.Name, tbl.PrimaryKey ?? "Id", StringComparison.OrdinalIgnoreCase))
?? tbl.Columns.First();
var pkType = MapCSharpType(pkCol.DataType);
return $@"using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using {nsApp}.DTOs;
using {nsApp}.Interfaces;
namespace {nsApi}.Controllers;
[ApiController]
[Route(""api/[controller]"")]
public class {entity}Controller : ControllerBase
{{
private readonly I{entity}Service _svc;
public {entity}Controller(I{entity}Service svc) => _svc = svc;
[HttpGet]
public async Task<IEnumerable<{entity}ReadDto>> GetAll() => await _svc.GetAllAsync();
[HttpGet(""{{id}}"", Name = ""Get{entity}ById"")]
public async Task<ActionResult<{entity}ReadDto>> Get({pkType} id)
{{
var r = await _svc.GetAsync(id);
return r is null ? NotFound() : Ok(r);
}}
[Authorize(Roles = ""Admin"")]
[HttpPost]
public async Task<ActionResult<{entity}ReadDto>> Create({entity}CreateDto dto)
{{
var r = await _svc.CreateAsync(dto);
var id = typeof({entity}ReadDto).GetProperty(""Id"")?.GetValue(r);
return Created($""/api/{entity}/{{id}}"", r);
}}
[Authorize(Roles = ""Admin"")]
[HttpPut(""{{id}}"")]
public async Task<ActionResult<{entity}ReadDto>> Update({pkType} id, {entity}UpdateDto dto)
{{
var r = await _svc.UpdateAsync(id, dto);
return r is null ? NotFound() : Ok(r);
}}
[Authorize(Roles = ""Admin"")]
[HttpDelete(""{{id}}"")]
public async Task<IActionResult> Delete({pkType} id)
{{
var ok = await _svc.DeleteAsync(id);
return ok ? NoContent() : NotFound();
}}
}}";
}
// ---------------- API Program.cs ----------------
public static string GenerateApiProgramCs(string nsApp, string nsInfra, string nsApi)
{
return $@"using Microsoft.OpenApi.Models;
using {nsApp};
using {nsInfra};
using {nsApi}.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{{
c.SwaggerDoc(""v1"", new OpenApiInfo {{ Title = ""API"", Version = ""v1"" }});
var scheme = new OpenApiSecurityScheme
{{
Name = ""Authorization"",
Type = SecuritySchemeType.Http,
Scheme = ""bearer"",
BearerFormat = ""JWT"",
In = ParameterLocation.Header
}};
c.AddSecurityDefinition(""Bearer"", scheme);
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{{
{{
new OpenApiSecurityScheme
{{
Reference = new OpenApiReference
{{
Type = ReferenceType.SecurityScheme,
Id = ""Bearer""
}}
}},
new string[] {{ }}
}}
}});
}});
builder.Services.AddApplication();
builder.Services.AddInfrastructure(builder.Configuration);
var app = builder.Build();
app.UseSwagger();
app.UseSwaggerUI();
app.UseHttpsRedirection();
app.UseGlobalException();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();";
}
// ---------------- API .csproj ----------------
public static string GenerateApiCsproj(string projectName)
{
return $@"<Project Sdk=""Microsoft.NET.Sdk.Web"">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include=""..\\{projectName}.Application\\{projectName}.Application.csproj"" />
<ProjectReference Include=""..\\{projectName}.Infrastructure\\{projectName}.Infrastructure.csproj"" />
</ItemGroup>
<ItemGroup>
<PackageReference Include=""Microsoft.AspNetCore.OpenApi"" Version=""8.0.7"" />
<PackageReference Include=""Swashbuckle.AspNetCore"" Version=""6.6.2"" />
<PackageReference Include=""Microsoft.AspNetCore.Authentication.JwtBearer"" Version=""8.0.7"" />
</ItemGroup>
</Project>";
}
}
}
0 comments:
Post a Comment