Skip to content

Commit

Permalink
New code gen foundations (#72)
Browse files Browse the repository at this point in the history
* Initial refactor and introduction of handlebars.

* Model generation complete.

* Entity/model gen converted.

* Ported IEntityManager, EntityManager, IEntityDataSvc and IEntityData.

* Ported DataSvc code-gen.

* Ported Data layer.

* Code tidy-up/consistency.

* Ported EntityController.

* A couple of minor fixes for "all" code-gen.

* Ported EntityAgent.

* Ported Business-layer ServiceCollectionExtensions.

* Ported ReferenceData code-gen (except data layer).

* Ported RefData Data code-gen.

* Ported partial gRPC code-gen.

* Completed gRPC code-gen port.

* Re codegen for CDR.

* Start laying foundation for database port to handlebars.

* Create new My.Hr sample to document and test end-to-end usage.

* Re-gen all other samples and re-test all.

* Upgrade the template solution and ensure functioning as expected. Refine My.Hr docs. Correct any further code-gen defects found.

* Implement My.Hr PerformanceReview example.
Introduced new ValidationTester for mocked unit testing. Updated example tests and solution template accordingly.

* Tools updated to return correct status code. Tweaked database tool to support new args,

* Handle a NotFoundException for an HTTP DELETE and return NoContent. All Data updates "have" to pre-query to enable proper mapping. ProperyMapping null source value fixes.

* Doco update and end-to-end test.

* Grpc Delete NotFound to be no content. Further tweak doco. Finally done; release it!
  • Loading branch information
chullybun authored Sep 21, 2020
1 parent 16eaafc commit b0f4511
Show file tree
Hide file tree
Showing 469 changed files with 21,684 additions and 13,531 deletions.
67 changes: 66 additions & 1 deletion Beef.sln
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,38 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Beef.Demo.Abc.Database", "s
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Grpc", "Grpc", "{3C2DB788-C4D6-48E7-9E26-9563B1C59EB5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Beef.Grpc", "src\Beef.Grpc\Beef.Grpc.csproj", "{2AD5436B-10AB-4312-AD25-A9EB70E0C92D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Beef.Grpc", "src\Beef.Grpc\Beef.Grpc.csproj", "{2AD5436B-10AB-4312-AD25-A9EB70E0C92D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "My.Hr", "My.Hr", "{FEA11C67-E7C7-49BC-99F5-5E5BF8F8674F}"
ProjectSection(SolutionItems) = preProject
samples\My.Hr\README.md = samples\My.Hr\README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Testing", "Testing", "{00C76124-DB2C-4653-B8C1-F7260784EA5A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{BFA3B544-8437-4158-A98F-84491B12F472}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "My.Hr.CodeGen", "samples\My.Hr\My.Hr.CodeGen\My.Hr.CodeGen.csproj", "{E773F133-A920-49A9-96BD-F7BD73A63D0C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "My.Hr.Database", "samples\My.Hr\My.Hr.Database\My.Hr.Database.csproj", "{9DEA75E3-5F77-40F5-B8E1-CB5028C41D9F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "My.Hr.Api", "samples\My.Hr\My.Hr.Api\My.Hr.Api.csproj", "{B7D52220-ABD0-40B7-9D23-E51B344D97B8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "My.Hr.Business", "samples\My.Hr\My.Hr.Business\My.Hr.Business.csproj", "{BD7BDE9B-7F1A-484A-95C3-A5ACCA2A2DA8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "My.Hr.Common", "samples\My.Hr\My.Hr.Common\My.Hr.Common.csproj", "{F962F1CC-DA7C-4146-8D36-0E6C74C261E5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "My.Hr.Test", "samples\My.Hr\My.Hr.Test\My.Hr.Test.csproj", "{54B168EB-C74D-4588-9D9E-BDD386D84C1F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{2429F084-A3F8-4F8A-88FF-E3BF5B210C13}"
ProjectSection(SolutionItems) = preProject
samples\My.Hr\docs\Employee-Api.md = samples\My.Hr\docs\Employee-Api.md
samples\My.Hr\docs\Employee-DB.md = samples\My.Hr\docs\Employee-DB.md
samples\My.Hr\docs\Employee-Search.md = samples\My.Hr\docs\Employee-Search.md
samples\My.Hr\docs\Employee-Terminate.md = samples\My.Hr\docs\Employee-Terminate.md
samples\My.Hr\docs\Employee-Test.md = samples\My.Hr\docs\Employee-Test.md
samples\My.Hr\docs\Performance-Review.md = samples\My.Hr\docs\Performance-Review.md
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -245,6 +276,30 @@ Global
{2AD5436B-10AB-4312-AD25-A9EB70E0C92D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2AD5436B-10AB-4312-AD25-A9EB70E0C92D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2AD5436B-10AB-4312-AD25-A9EB70E0C92D}.Release|Any CPU.Build.0 = Release|Any CPU
{E773F133-A920-49A9-96BD-F7BD73A63D0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E773F133-A920-49A9-96BD-F7BD73A63D0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E773F133-A920-49A9-96BD-F7BD73A63D0C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E773F133-A920-49A9-96BD-F7BD73A63D0C}.Release|Any CPU.Build.0 = Release|Any CPU
{9DEA75E3-5F77-40F5-B8E1-CB5028C41D9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9DEA75E3-5F77-40F5-B8E1-CB5028C41D9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9DEA75E3-5F77-40F5-B8E1-CB5028C41D9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9DEA75E3-5F77-40F5-B8E1-CB5028C41D9F}.Release|Any CPU.Build.0 = Release|Any CPU
{B7D52220-ABD0-40B7-9D23-E51B344D97B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B7D52220-ABD0-40B7-9D23-E51B344D97B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B7D52220-ABD0-40B7-9D23-E51B344D97B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B7D52220-ABD0-40B7-9D23-E51B344D97B8}.Release|Any CPU.Build.0 = Release|Any CPU
{BD7BDE9B-7F1A-484A-95C3-A5ACCA2A2DA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BD7BDE9B-7F1A-484A-95C3-A5ACCA2A2DA8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BD7BDE9B-7F1A-484A-95C3-A5ACCA2A2DA8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BD7BDE9B-7F1A-484A-95C3-A5ACCA2A2DA8}.Release|Any CPU.Build.0 = Release|Any CPU
{F962F1CC-DA7C-4146-8D36-0E6C74C261E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F962F1CC-DA7C-4146-8D36-0E6C74C261E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F962F1CC-DA7C-4146-8D36-0E6C74C261E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F962F1CC-DA7C-4146-8D36-0E6C74C261E5}.Release|Any CPU.Build.0 = Release|Any CPU
{54B168EB-C74D-4588-9D9E-BDD386D84C1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{54B168EB-C74D-4588-9D9E-BDD386D84C1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{54B168EB-C74D-4588-9D9E-BDD386D84C1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{54B168EB-C74D-4588-9D9E-BDD386D84C1F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -293,6 +348,16 @@ Global
{5D6F532E-7DAC-40B3-8A65-D557B34C3605} = {104CA8C9-84F6-4B5C-9576-F25ADA255CF0}
{3C2DB788-C4D6-48E7-9E26-9563B1C59EB5} = {6C902314-82BD-48FD-8777-5C3AC986E4D3}
{2AD5436B-10AB-4312-AD25-A9EB70E0C92D} = {3C2DB788-C4D6-48E7-9E26-9563B1C59EB5}
{FEA11C67-E7C7-49BC-99F5-5E5BF8F8674F} = {2CD70532-8E64-46DF-A895-B41234BAC290}
{00C76124-DB2C-4653-B8C1-F7260784EA5A} = {FEA11C67-E7C7-49BC-99F5-5E5BF8F8674F}
{BFA3B544-8437-4158-A98F-84491B12F472} = {FEA11C67-E7C7-49BC-99F5-5E5BF8F8674F}
{E773F133-A920-49A9-96BD-F7BD73A63D0C} = {BFA3B544-8437-4158-A98F-84491B12F472}
{9DEA75E3-5F77-40F5-B8E1-CB5028C41D9F} = {BFA3B544-8437-4158-A98F-84491B12F472}
{B7D52220-ABD0-40B7-9D23-E51B344D97B8} = {FEA11C67-E7C7-49BC-99F5-5E5BF8F8674F}
{BD7BDE9B-7F1A-484A-95C3-A5ACCA2A2DA8} = {FEA11C67-E7C7-49BC-99F5-5E5BF8F8674F}
{F962F1CC-DA7C-4146-8D36-0E6C74C261E5} = {FEA11C67-E7C7-49BC-99F5-5E5BF8F8674F}
{54B168EB-C74D-4588-9D9E-BDD386D84C1F} = {00C76124-DB2C-4653-B8C1-F7260784EA5A}
{2429F084-A3F8-4F8A-88FF-E3BF5B210C13} = {FEA11C67-E7C7-49BC-99F5-5E5BF8F8674F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {42D71086-61E6-4D31-B4B8-BFC8CC471428}
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ The following samples are provided to guide usage:

Sample | Description
-|-
[`My.Hr`](./samples/My.Hr) | A sample as an end-to-end solution walkthrough to demonstrate the usage of _Beef_ within the context of a fictitious Human Resources solution. The main intent is to show how _Beef_ can be used against a relational database (SQL Server) leveraging both direct ADO.NET (with stored procedures) and Entity Framework (EF) where applicable.
[`Cdr.Banking`](./samples/Cdr.Banking) | A sample as an end-to-end solution to demonstrate _Beef_ being used to solve a real-world scenario. This demonstrates an implementation of the [CDR](https://consumerdatastandards.org.au/) [Banking](https://consumerdatastandardsaustralia.github.io/standards/#consumer-data-standards-banking-apis) APIs leveraging a Cosmos DB data source.
[`Demo`](./samples/Demo) | A sample as an end-to-end solution to demonstrate the tiering & layering, code-generation, database management and automated intra-domain integration testing. This is primarily used to further test the key end-to-end capabilities enabled by _Beef_.

Expand Down Expand Up @@ -219,11 +220,16 @@ _Beef_ is open source under the [MIT license](./LICENSE) and is free for commerc

To start using _Beef_ you do not need to clone or fork the repo; you just need to create a solution with the underlying projects using the prescribed [solution structure](./docs/Solution-Structure.md), including referencing the appropriate [NuGet packages](#Framework). To accelerate this a .NET Core [template capability](./templates/Beef.Template.Solution/README.md) is provided to enable you to get up and running in minutes.

See the following for example end-to-end usage; each demonstrating the same API functionality leveraging different data sources to accomplish:
See the following for example end-to-end solution/project creation; each demonstrating the same API functionality leveraging different data sources to accomplish:
- [Cosmos sample](./docs/Sample-Cosmos-GettingStarted.md)
- [Database Stored Procedures sample](./docs/Sample-StoredProcs-GettingStarted.md)
- [Database Entity Framework sample](./docs/Sample-EntityFramework-GettingStarted.md)

Otherwise, follow along with the following sample tutorials that will provide a more in-depth walkthrough solving a defined functional problem:

- [`My.Hr`](./samples/My.Hr)
- [`Cdr.Banking`](./samples/Cdr.Banking)

<br/>

## Contributing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,32 @@
namespace Cdr.Banking.Api.Controllers
{
/// <summary>
/// Provides the <b>Account</b> Web API functionality.
/// Provides the <see cref="Account"/> Web API functionality.
/// </summary>
[AllowAnonymous]
[Route("api/v1/banking/accounts")]
public partial class AccountController : ControllerBase
{
private readonly IAccountManager _manager;

/// <summary>
/// Initializes a new instance of the <see cref="AccountController"/> class.
/// </summary>
/// <param name="manager">The <see cref="IAccountManager"/>.</param>
public AccountController(IAccountManager manager) => _manager = Check.NotNull(manager, nameof(manager));
public AccountController(IAccountManager manager)
{ _manager = Check.NotNull(manager, nameof(manager)); AccountControllerCtor(); }

partial void AccountControllerCtor(); // Enables additional functionality to be added to the constructor.

/// <summary>
/// Get all accounts.
/// </summary>
/// <param name="productCategory">The Product Category (see <see cref="RefDataNamespace.ProductCategory"/>).</param>
/// <param name="openStatus">The Open Status (see <see cref="RefDataNamespace.OpenStatus"/>).</param>
/// <param name="isOwned">The Is Owned.</param>
/// <returns>A <see cref="AccountCollection"/>.</returns>
[HttpGet()]
[Route("")]
/// <param name="isOwned">Indicates whether Is Owned.</param>
/// <returns>The <see cref="AccountCollection"/></returns>
[AllowAnonymous]
[HttpGet("")]
[ProducesResponseType(typeof(AccountCollection), (int)HttpStatusCode.OK)]
[ProducesResponseType((int)HttpStatusCode.NoContent)]
public IActionResult GetAccounts([FromQuery(Name = "product-category")] string? productCategory = default, [FromQuery(Name = "open-status")] string? openStatus = default, [FromQuery(Name = "is-owned")] bool? isOwned = default)
Expand All @@ -56,9 +60,9 @@ public IActionResult GetAccounts([FromQuery(Name = "product-category")] string?
/// Get <see cref="AccountDetail"/>.
/// </summary>
/// <param name="accountId">The <see cref="Account"/> identifier.</param>
/// <returns>The selected <see cref="AccountDetail"/> entity where found.</returns>
[HttpGet()]
[Route("{accountId}")]
/// <returns>The selected <see cref="AccountDetail"/> where found.</returns>
[AllowAnonymous]
[HttpGet("{accountId}")]
[ProducesResponseType(typeof(AccountDetail), (int)HttpStatusCode.OK)]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public IActionResult GetDetail(string? accountId)
Expand All @@ -71,9 +75,9 @@ public IActionResult GetDetail(string? accountId)
/// Get <see cref="Account"/> <see cref="Balance"/>.
/// </summary>
/// <param name="accountId">The <see cref="Account"/> identifier.</param>
/// <returns>The selected <see cref="Balance"/> entity where found.</returns>
[HttpGet()]
[Route("{accountId}/balance")]
/// <returns>The selected <see cref="Balance"/> where found.</returns>
[AllowAnonymous]
[HttpGet("{accountId}/balance")]
[ProducesResponseType(typeof(Balance), (int)HttpStatusCode.OK)]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public IActionResult GetBalance(string? accountId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ namespace Cdr.Banking.Api.Controllers
/// <summary>
/// Provides the <b>ReferenceData</b> Web API functionality.
/// </summary>
[AllowAnonymous]
public partial class ReferenceDataController : ControllerBase
{
/// <summary>
/// Gets all of the <see cref="RefDataNamespace.OpenStatus"/> reference data entities that match the specified criteria.
/// Gets all of the <see cref="RefDataNamespace.OpenStatus"/> reference data items that match the specified criteria.
/// </summary>
/// <param name="codes">The reference data code list.</param>
/// <param name="text">The reference data text (including wildcards).</param>
/// <returns>A <see cref="RefDataNamespace.OpenStatus"/> collection.</returns>
/// <returns>A RefDataNamespace.OpenStatus collection.</returns>
[AllowAnonymous]
[HttpGet()]
[Route("api/v1/ref/openStatuses")]
[ProducesResponseType(typeof(IEnumerable<RefDataNamespace.OpenStatus>), (int)HttpStatusCode.OK)]
Expand All @@ -41,11 +43,12 @@ public partial class ReferenceDataController : ControllerBase
operationType: OperationType.Read, statusCode: HttpStatusCode.OK, alternateStatusCode: HttpStatusCode.NoContent);

/// <summary>
/// Gets all of the <see cref="RefDataNamespace.ProductCategory"/> reference data entities that match the specified criteria.
/// Gets all of the <see cref="RefDataNamespace.ProductCategory"/> reference data items that match the specified criteria.
/// </summary>
/// <param name="codes">The reference data code list.</param>
/// <param name="text">The reference data text (including wildcards).</param>
/// <returns>A <see cref="RefDataNamespace.ProductCategory"/> collection.</returns>
/// <returns>A RefDataNamespace.ProductCategory collection.</returns>
[AllowAnonymous]
[HttpGet()]
[Route("api/v1/ref/productCategories")]
[ProducesResponseType(typeof(IEnumerable<RefDataNamespace.ProductCategory>), (int)HttpStatusCode.OK)]
Expand All @@ -55,11 +58,12 @@ public partial class ReferenceDataController : ControllerBase
operationType: OperationType.Read, statusCode: HttpStatusCode.OK, alternateStatusCode: HttpStatusCode.NoContent);

/// <summary>
/// Gets all of the <see cref="RefDataNamespace.AccountUType"/> reference data entities that match the specified criteria.
/// Gets all of the <see cref="RefDataNamespace.AccountUType"/> reference data items that match the specified criteria.
/// </summary>
/// <param name="codes">The reference data code list.</param>
/// <param name="text">The reference data text (including wildcards).</param>
/// <returns>A <see cref="RefDataNamespace.AccountUType"/> collection.</returns>
/// <returns>A RefDataNamespace.AccountUType collection.</returns>
[AllowAnonymous]
[HttpGet()]
[Route("api/v1/ref/accountUTypes")]
[ProducesResponseType(typeof(IEnumerable<RefDataNamespace.AccountUType>), (int)HttpStatusCode.OK)]
Expand All @@ -69,11 +73,12 @@ public partial class ReferenceDataController : ControllerBase
operationType: OperationType.Read, statusCode: HttpStatusCode.OK, alternateStatusCode: HttpStatusCode.NoContent);

/// <summary>
/// Gets all of the <see cref="RefDataNamespace.MaturityInstructions"/> reference data entities that match the specified criteria.
/// Gets all of the <see cref="RefDataNamespace.MaturityInstructions"/> reference data items that match the specified criteria.
/// </summary>
/// <param name="codes">The reference data code list.</param>
/// <param name="text">The reference data text (including wildcards).</param>
/// <returns>A <see cref="RefDataNamespace.MaturityInstructions"/> collection.</returns>
/// <returns>A RefDataNamespace.MaturityInstructions collection.</returns>
[AllowAnonymous]
[HttpGet()]
[Route("api/v1/ref/maturityInstructions")]
[ProducesResponseType(typeof(IEnumerable<RefDataNamespace.MaturityInstructions>), (int)HttpStatusCode.OK)]
Expand All @@ -83,11 +88,12 @@ public partial class ReferenceDataController : ControllerBase
operationType: OperationType.Read, statusCode: HttpStatusCode.OK, alternateStatusCode: HttpStatusCode.NoContent);

/// <summary>
/// Gets all of the <see cref="RefDataNamespace.TransactionType"/> reference data entities that match the specified criteria.
/// Gets all of the <see cref="RefDataNamespace.TransactionType"/> reference data items that match the specified criteria.
/// </summary>
/// <param name="codes">The reference data code list.</param>
/// <param name="text">The reference data text (including wildcards).</param>
/// <returns>A <see cref="RefDataNamespace.TransactionType"/> collection.</returns>
/// <returns>A RefDataNamespace.TransactionType collection.</returns>
[AllowAnonymous]
[HttpGet()]
[Route("api/v1/ref/transactionTypes")]
[ProducesResponseType(typeof(IEnumerable<RefDataNamespace.TransactionType>), (int)HttpStatusCode.OK)]
Expand All @@ -97,11 +103,12 @@ public partial class ReferenceDataController : ControllerBase
operationType: OperationType.Read, statusCode: HttpStatusCode.OK, alternateStatusCode: HttpStatusCode.NoContent);

/// <summary>
/// Gets all of the <see cref="RefDataNamespace.TransactionStatus"/> reference data entities that match the specified criteria.
/// Gets all of the <see cref="RefDataNamespace.TransactionStatus"/> reference data items that match the specified criteria.
/// </summary>
/// <param name="codes">The reference data code list.</param>
/// <param name="text">The reference data text (including wildcards).</param>
/// <returns>A <see cref="RefDataNamespace.TransactionStatus"/> collection.</returns>
/// <returns>A RefDataNamespace.TransactionStatus collection.</returns>
[AllowAnonymous]
[HttpGet()]
[Route("api/v1/ref/transactionStatuses")]
[ProducesResponseType(typeof(IEnumerable<RefDataNamespace.TransactionStatus>), (int)HttpStatusCode.OK)]
Expand All @@ -111,9 +118,10 @@ public partial class ReferenceDataController : ControllerBase
operationType: OperationType.Read, statusCode: HttpStatusCode.OK, alternateStatusCode: HttpStatusCode.NoContent);

/// <summary>
/// Gets the reference data entries for the specified entities and codes from the query string; e.g: api/v1/ref?entity=codeX,codeY&amp;entity2=codeZ&amp;entity3
/// Gets the reference data entries for the specified entities and codes from the query string; e.g: ?entity=codeX,codeY&amp;entity2=codeZ&amp;entity3
/// </summary>
/// <returns>A <see cref="ReferenceDataMultiCollection"/>.</returns>
[AllowAnonymous]
[HttpGet()]
[Route("api/v1/ref")]
[ProducesResponseType(typeof(ReferenceDataMultiCollection), (int)HttpStatusCode.OK)]
Expand Down
Loading

0 comments on commit b0f4511

Please sign in to comment.