Skip to content

Commit

Permalink
published for .NET 8
Browse files Browse the repository at this point in the history
  • Loading branch information
zijianhuang committed Jun 23, 2024
1 parent 6fb9e65 commit 7aae3c0
Show file tree
Hide file tree
Showing 21 changed files with 619 additions and 585 deletions.
372 changes: 186 additions & 186 deletions DemoCoreWeb.ClientApi/WebApiClientAuto.cs

Large diffs are not rendered by default.

167 changes: 85 additions & 82 deletions DemoCoreWebControllers/Controllers/CodeGenController.cs
Original file line number Diff line number Diff line change
@@ -1,82 +1,85 @@
#if DEBUG //This controller is not needed in production release, since the client API should be generated during development of the Web Api.
using Fonlow.CodeDom.Web;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using System.Net;

namespace Fonlow.WebApiClientGen
{
[ApiExplorerSettings(IgnoreApi = true)]
[ApiController]
[Route("api/[controller]")]
public class CodeGenController : ControllerBase
{
private readonly IApiDescriptionGroupCollectionProvider apiExplorer;
private readonly string webRootPath;

/// <summary>
/// For injecting some environment config by the run time.
/// </summary>
/// <param name="apiExplorer"></param>
/// <param name="hostingEnvironment"></param>
public CodeGenController(IApiDescriptionGroupCollectionProvider apiExplorer, IWebHostEnvironment hostingEnvironment)
{
this.apiExplorer = apiExplorer;
this.webRootPath = hostingEnvironment.WebRootPath;
}

/// <summary>
/// Trigger the API to generate WebApiClientAuto.cs for an established client API project.
/// </summary>
/// <param name="settings"></param>
/// <returns>OK if OK</returns>
[HttpPost]
public IActionResult TriggerCodeGen([FromBody] CodeGenSettings settings)
{
if (settings == null)
return BadRequest("No settings");

if (settings.ClientApiOutputs == null)
return BadRequest("No settings/ClientApiOutputs");

Fonlow.Web.Meta.WebApiDescription[] webApiDescriptions;
try
{
ApiDescription[] descriptions = ApiExplorerHelper.GetApiDescriptions(apiExplorer);
webApiDescriptions = descriptions.Select(d => Fonlow.Web.Meta.MetaTransform.GetWebApiDescription(d)).OrderBy(d => d.ActionDescriptor.ActionName).ToArray();

}
catch (Fonlow.Web.Meta.CodeGenException e)
{
System.Diagnostics.Trace.TraceWarning(e.Message);
return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
}
catch (System.InvalidOperationException e)
{
System.Diagnostics.Trace.TraceWarning(e.Message);
return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
}

if (!settings.ClientApiOutputs.CamelCase.HasValue)
{
settings.ClientApiOutputs.CamelCase = true;
}

try
{
CodeGen.GenerateClientAPIs(this.webRootPath, settings, webApiDescriptions);
}
catch (Fonlow.Web.Meta.CodeGenException e)
{
string msg = e.Message + (string.IsNullOrEmpty(e.Description) ? string.Empty : (" : " + e.Description));
System.Diagnostics.Trace.TraceError(msg);
return BadRequest(msg);
}

return Ok("Done");
}
}

}
#endif
#if DEBUG //This controller is not needed in production release, since the client API should be generated during development of the Web Api.
using Fonlow.CodeDom.Web;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using System.Net;

namespace Fonlow.WebApiClientGen
{
/// <summary>
/// For CodeGen triggered by a client call.
/// </summary>
[ApiExplorerSettings(IgnoreApi = true)]
[ApiController]
[Route("api/[controller]")]
public class CodeGenController : ControllerBase
{
private readonly IApiDescriptionGroupCollectionProvider apiExplorer;
private readonly string webRootPath;

/// <summary>
/// For injecting some environment config by the run time.
/// </summary>
/// <param name="apiExplorer"></param>
/// <param name="hostingEnvironment"></param>
public CodeGenController(IApiDescriptionGroupCollectionProvider apiExplorer, IWebHostEnvironment hostingEnvironment)
{
this.apiExplorer = apiExplorer;
this.webRootPath = hostingEnvironment.WebRootPath;
}

/// <summary>
/// Trigger the API to generate WebApiClientAuto.cs for an established client API project.
/// </summary>
/// <param name="settings"></param>
/// <returns>OK if OK</returns>
[HttpPost]
public IActionResult TriggerCodeGen([FromBody] CodeGenSettings settings)
{
if (settings == null)
return BadRequest("No settings");

if (settings.ClientApiOutputs == null)
return BadRequest("No settings/ClientApiOutputs");

Fonlow.Web.Meta.WebApiDescription[] webApiDescriptions;
try
{
ApiDescription[] descriptions = ApiExplorerHelper.GetApiDescriptions(apiExplorer);
webApiDescriptions = descriptions.Select(d => Fonlow.Web.Meta.MetaTransform.GetWebApiDescription(d)).OrderBy(d => d.ActionDescriptor.ActionName).ToArray();

}
catch (Fonlow.Web.Meta.CodeGenException e)
{
Console.Error.WriteLine(e.Message);
return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
}
catch (System.InvalidOperationException e)
{
Console.Error.WriteLine(e.Message);
return StatusCode((int)HttpStatusCode.InternalServerError, e.Message);
}

if (!settings.ClientApiOutputs.CamelCase.HasValue)
{
settings.ClientApiOutputs.CamelCase = true;
}

try
{
CodeGen.GenerateClientAPIs(this.webRootPath, settings, webApiDescriptions);
}
catch (Fonlow.Web.Meta.CodeGenException e)
{
string msg = e.Message + (string.IsNullOrEmpty(e.Description) ? string.Empty : (" : " + e.Description));
Console.Error.WriteLine(msg);
return BadRequest(msg);
}

return Ok("Done");
}
}

}
#endif
57 changes: 44 additions & 13 deletions DemoCoreWebControllers/Controllers/HeroesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,54 @@ public SuperHero(long id, string name, bool super):base(id, name)

}

//public sealed class HeroesData
//{
// public ConcurrentDictionary<long, Hero> Dic { get; private set; }

// private HeroesData()
// {
// Dic = new ConcurrentDictionary<long, Hero>(new KeyValuePair<long, Hero>[] {
// new KeyValuePair<long, Hero>(11, new Hero(11, "Mr. Nice")),
// new KeyValuePair<long, Hero>(12, new Hero(12, "Narco")),
// new KeyValuePair<long, Hero>(13, new Hero(13, "Bombasto")),
// new KeyValuePair<long, Hero>(14, new Hero(14, "Celeritas")),
// new KeyValuePair<long, Hero>(15, new Hero(15, "Magneta")),
// new KeyValuePair<long, Hero>(16, new Hero(16, "RubberMan")),
// new KeyValuePair<long, Hero>(17, new Hero(17, "Dynama")),
// new KeyValuePair<long, Hero>(18, new Hero(18, "Dr IQ")),
// new KeyValuePair<long, Hero>(19, new Hero(19, "Magma")),
// new KeyValuePair<long, Hero>(20, new Hero(29, "Tornado")),

// });
// }

// public static HeroesData Instance { get { return Nested.instance; } }

// private class Nested
// {
// // Explicit static constructor to tell C# compiler
// // not to mark type as beforefieldinit
// static Nested()
// {
// }

// internal static readonly HeroesData instance = new HeroesData();
// }
//}

/// <summary>
///
/// </summary>
/// <remarks>The 6th version of singleton is better in all threaded environments</remarks>
public sealed class HeroesData
{
public ConcurrentDictionary<long, Hero> Dic { get; private set; }

private static readonly Lazy<HeroesData> lazy =
new Lazy<HeroesData>(() => new HeroesData());

public static HeroesData Instance { get { return lazy.Value; } }

private HeroesData()
{
Dic = new ConcurrentDictionary<long, Hero>(new KeyValuePair<long, Hero>[] {
Expand All @@ -214,18 +258,5 @@ private HeroesData()

});
}

public static HeroesData Instance { get { return Nested.instance; } }

private class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}

internal static readonly HeroesData instance = new HeroesData();
}
}
}
Loading

0 comments on commit 7aae3c0

Please sign in to comment.