Skip to content

Commit

Permalink
CHORE: Reorganize source files structure (#36)
Browse files Browse the repository at this point in the history
Closes #28

Because of the new structure, the previous template shortcuts need to be
renamed, so this breaking change will be reflected in the version number
going to v2.0.

Also, as a consequence, the Nuget package is also intended to be
renamed, so the old one will be deprecated to give place to the new
-more generic- one.
  • Loading branch information
CesarD authored Jan 31, 2023
1 parent 710a82a commit 8d68452
Show file tree
Hide file tree
Showing 249 changed files with 3,782 additions and 3,788 deletions.
24 changes: 13 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
![Logo Monaco](monaco-transp.png)
-

[![Nuget version](https://img.shields.io/nuget/v/Monaco.Template.Solution?style=plastic)](https://www.nuget.org/packages/Monaco.Template.Solution)
[![Nuget downloads](https://img.shields.io/nuget/dt/Monaco.Template.Solution?style=plastic)](https://www.nuget.org/packages/Monaco.Template.Solution)
[![Nuget version](https://img.shields.io/nuget/v/Monaco.Template?style=plastic)](https://www.nuget.org/packages/Monaco.Template)
[![Nuget downloads](https://img.shields.io/nuget/dt/Monaco.Template?style=plastic)](https://www.nuget.org/packages/Monaco.Template)
[![License](https://img.shields.io/github/license/OneBeyond/monaco?style=plastic)](LICENSE.TXT)
[![Release to NuGet](https://github.com/onebeyond/monaco/actions/workflows/release.yml/badge.svg)](https://github.com/onebeyond/monaco/actions/workflows/release.yml)

# Introduction
Monaco is a .NET solution template that provides the scaffolding for a .NET solution based on the [Vertical Slices Architecture](https://www.youtube.com/watch?v=SUiWfhAhgQw).
# Introduction
Monaco is meant to be a set of .NET templates for different platforms, such as a backend with a REST API, a Blazor WASM webapp or a .NET MAUI desktop/mobile app (the last 2 are planned [here](https://github.com/onebeyond/monaco/milestone/1) and [here](https://github.com/onebeyond/monaco/milestone/2)), as well as other individual files templates, all in order to help accelerate the development of new projects with a flexible and easy to understand architecture.

It ships the most basic structure required to run a REST API with EF Core and a rich model Domain, along with unit tests to cover the existing boilerplate.
The backend solution is based on the [Vertical Slices Architecture](https://www.youtube.com/watch?v=SUiWfhAhgQw). It ships the most basic structure required to run a REST API with EF Core and a rich model Domain, along with unit tests to cover the existing boilerplate.

It also provides some basic business components as example of real life implementation logic.
Each of the different solution templates also provide some basic business components as example of real life implementation logic.

# Getting Started

Expand All @@ -21,23 +21,25 @@ It also provides some basic business components as example of real life implemen

#### Installation

`dotnet new install Monaco.Template.Solution`
`dotnet new install Monaco.Template`

#### Uninstalling

`dotnet new uninstall Monaco.Template.Solution`
`dotnet new uninstall Monaco.Template`

#### How to create a Monaco based solution

`dotnet new monaco-solution -n MyFirstSolution`
For generating a new backend solution, you can run the following command:

This will create a folder named `MyFirstSolution`, which will contain a structure of directories prefixed with the name as part of the namespace declaration. The resulting solution will include the default layout and all the files required to run the application (more info about this [here](https://github.com/onebeyond/onebeyond/wiki/Solution-projects-structure))
`dotnet new monaco-backend-solution -n MyFirstSolution`

This will create a folder named `MyFirstSolution`, which will contain a structure of directories prefixed with the name as part of the namespace declaration. The resulting solution will include the default layout and all the files required to run the application (more info about this [here](https://github.com/onebeyond/monaco/wiki/Solution-projects-structure))

From there, is enough to configure `appsettings.json` with the required settings and run the app.

#### Getting help about template's options

`dotnet new monaco-solution --help`
`dotnet new monaco-backend-solution --help`

(For more information about Monaco options please refer [here](https://github.com/onebeyond/monaco/wiki/Template-options))

Expand Down
File renamed without changes.
File renamed without changes
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "One Beyond",
"classifications": [ "Web", "Solution" ],
"name": "Monaco Solution Template",
"description": "Solution template for .NET projects",
"groupIdentity": "Monaco.Template",
"identity": "Monaco.Template.Solution",
"shortName": "monaco-solution",
"classifications": [ "Web", "Solution", "Cloud", "WebAPI" ],
"name": "Monaco Backend Solution Template",
"description": "Solution template for backend .NET projects",
"groupIdentity": "Monaco.Template.Backend",
"identity": "Monaco.Template.Backend.Solution",
"shortName": "monaco-backend-solution",
"preferNameDirectory": true,
"sourceName": "Monaco.Template",
"sourceName": "Monaco.Template.Backend",
"tags": {
"language": "C#",
"type": "project"
},
"primaryOutputs": [
{
"path": "Monaco.Template.sln"
"path": "Monaco.Template.Backend.sln"
}
],
"symbols": {
Expand Down Expand Up @@ -152,45 +152,45 @@
"exclude": [
"nuget.config",
"realm-export-template.json",
"Monaco.Template.Common.*/**/*"
"Monaco.Template.Backend.Common.*/**/*"
]
},
{
"condition": "(!filesSupport)",
"exclude": [
"Monaco.Template.Common.BlobStorage/**/*",
"Monaco.Template.Api/Controllers/FilesController.cs",
"Monaco.Template.Api/Controllers/ImagesController.cs",
"Monaco.Template.Application/Features/File/**/*",
"Monaco.Template.Application/Features/Image/**/*",
"Monaco.Template.Application/DTOs/Extensions/FileExtensions.cs",
"Monaco.Template.Application/DTOs/File*.cs",
"Monaco.Template.Application/DTOs/ImageDto.cs",
"Monaco.Template.Application/Services/**/*FileService.*",
"Monaco.Template.Application.Infrastructure/EntityConfigurations/DocumentEntityConfiguration.cs",
"Monaco.Template.Application.Infrastructure/EntityConfigurations/FileEntityConfiguration.cs",
"Monaco.Template.Application.Infrastructure/EntityConfigurations/ImageEntityConfiguration.cs",
"Monaco.Template.Domain/Model/Document.cs",
"Monaco.Template.Domain/Model/File.cs",
"Monaco.Template.Domain/Model/Image.cs"
"Monaco.Template.Backend.Common.BlobStorage/**/*",
"Monaco.Template.Backend.Api/Controllers/FilesController.cs",
"Monaco.Template.Backend.Api/Controllers/ImagesController.cs",
"Monaco.Template.Backend.Application/Features/File/**/*",
"Monaco.Template.Backend.Application/Features/Image/**/*",
"Monaco.Template.Backend.Application/DTOs/Extensions/FileExtensions.cs",
"Monaco.Template.Backend.Application/DTOs/File*.cs",
"Monaco.Template.Backend.Application/DTOs/ImageDto.cs",
"Monaco.Template.Backend.Application/Services/**/*FileService.*",
"Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/DocumentEntityConfiguration.cs",
"Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/FileEntityConfiguration.cs",
"Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/ImageEntityConfiguration.cs",
"Monaco.Template.Backend.Domain/Model/Document.cs",
"Monaco.Template.Backend.Domain/Model/File.cs",
"Monaco.Template.Backend.Domain/Model/Image.cs"
]
},
{
"condition": "(!massTransitIntegration)",
"exclude": [
"Monaco.Template.Common.Messaging.Messages/**/*"
"Monaco.Template.Backend.Common.Messaging.Messages/**/*"
]
},
{
"condition": "(!apiGateway)",
"exclude": [
"Monaco.Template.Common.ApiGateway/**/*"
"Monaco.Template.Backend.Common.ApiGateway/**/*"
]
},
{
"condition": "(disableAuth)",
"exclude": [
"Monaco.Template.Api/Auth/**/*"
"Monaco.Template.Backend.Api/Auth/**/*"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
#if (!disableAuth)
namespace Monaco.Template.Api.Auth;

namespace Monaco.Template.Backend.Api.Auth;

public static class Scopes
{
public const string CompaniesRead = "companies:read";
public const string CompaniesWrite = "companies:write";
public const string CompaniesRead = "companies:read";
public const string CompaniesWrite = "companies:write";
#if filesSupport
public const string FilesRead = "files:read";
public const string FilesWrite = "files:write";
#endif

public static List<string> List => new()
{
CompaniesRead,
CompaniesWrite,
public static List<string> List => new()
{
CompaniesRead,
CompaniesWrite,
#if filesSupport
FilesRead,
FilesWrite
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
using Monaco.Template.Api.DTOs.Extensions;
using Monaco.Template.Application.DTOs;
using Monaco.Template.Application.Features.Company.Commands;
using Monaco.Template.Application.Features.Company.Queries;
using Monaco.Template.Common.Api.Application;
using Monaco.Template.Common.Api.Application.Enums;
using Monaco.Template.Common.Domain.Model;
using MediatR;
using MediatR;
#if (!disableAuth)
using Microsoft.AspNetCore.Authorization;
#endif
using Microsoft.AspNetCore.Mvc;
using Monaco.Template.Backend.Api.DTOs;
#if (!disableAuth)
using Monaco.Template.Api.Auth;
using Monaco.Template.Backend.Api.DTOs.Extensions;
using Monaco.Template.Backend.Api.Auth;
#endif
using Monaco.Template.Api.DTOs;
using Monaco.Template.Backend.Application.DTOs;
using Monaco.Template.Backend.Application.Features.Company.Commands;
using Monaco.Template.Backend.Application.Features.Company.Queries;
using Monaco.Template.Backend.Common.Api.Application;
using Monaco.Template.Backend.Common.Api.Application.Enums;
using Monaco.Template.Backend.Common.Domain.Model;

namespace Monaco.Template.Api.Controllers;
namespace Monaco.Template.Backend.Api.Controllers;

[Route("api/v{apiVersion:apiVersion}/[controller]")]
[ApiController]
public class CompaniesController : ControllerBase
{
private readonly IMediator _mediator;
private readonly IMediator _mediator;

public CompaniesController(IMediator mediator)
{
_mediator = mediator;
}
}

[HttpGet]
[HttpGet]
#if (!disableAuth)
[Authorize(Scopes.CompaniesRead)]
#endif
Expand All @@ -39,14 +39,14 @@ public Task<ActionResult<Page<CompanyDto>>> Get() =>
#if (!disableAuth)
[Authorize(Scopes.CompaniesRead)]
#endif
public Task<ActionResult<CompanyDto?>> Get(Guid id) =>
public Task<ActionResult<CompanyDto?>> Get(Guid id) =>
_mediator.ExecuteQueryAsync(new GetCompanyByIdQuery(id));

[HttpPost]
#if (!disableAuth)
[Authorize(Scopes.CompaniesWrite)]
#endif
public Task<ActionResult<Guid>> Post([FromRoute] ApiVersion apiVersion, [FromBody] CompanyCreateEditDto dto) =>
public Task<ActionResult<Guid>> Post([FromRoute] ApiVersion apiVersion, [FromBody] CompanyCreateEditDto dto) =>
_mediator.ExecuteCommandAsync(dto.MapCreateCommand(),
ModelState,
"api/v{0}/Companies/{1}",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Monaco.Template.Backend.Application.DTOs;
using Monaco.Template.Backend.Application.Features.Country.Queries;
using Monaco.Template.Backend.Common.Api.Application;

namespace Monaco.Template.Backend.Api.Controllers;

[Route("api/v{apiVersion:apiVersion}/[controller]")]
[ApiController]
public class CountriesController : ControllerBase
{
private readonly IMediator _mediator;

public CountriesController(IMediator mediator)
{
_mediator = mediator;
}

/// <summary>
/// Gets a list of countries
/// </summary>
/// <returns></returns>
[HttpGet]
public Task<ActionResult<List<CountryDto>>> Get() =>
_mediator.ExecuteQueryAsync(new GetCountryListQuery(Request.Query));

/// <summary>
/// Gets a country by Id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("{id:guid}")]
public Task<ActionResult<CountryDto?>> Get(Guid id) =>
_mediator.ExecuteQueryAsync(new GetCountryByIdQuery(id));
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
#if filesSupport
#if (!disableAuth)
using Monaco.Template.Api.Auth;
using Monaco.Template.Backend.Api.Auth;
#endif
using Monaco.Template.Application.Features.File.Commands;
using Monaco.Template.Application.DTOs;
using Monaco.Template.Application.Features.File.Queries;
using Monaco.Template.Common.Api.Application;
using Monaco.Template.Backend.Application.Features.File.Commands;
using Monaco.Template.Backend.Application.DTOs;
using Monaco.Template.Backend.Application.Features.File.Queries;
using Monaco.Template.Backend.Common.Api.Application;
using MediatR;
#if (!disableAuth)
using Microsoft.AspNetCore.Authorization;
#endif
using Microsoft.AspNetCore.Mvc;
using System.Net;

namespace Monaco.Template.Api.Controllers
namespace Monaco.Template.Backend.Api.Controllers
{
[Route("api/v{apiVersion:apiVersion}/[controller]")]
[ApiController]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
#if filesSupport
#if (!disableAuth)
using Monaco.Template.Api.Auth;
using Monaco.Template.Backend.Api.Auth;
#endif
using Monaco.Template.Application.DTOs;
using Monaco.Template.Application.Features.File.Queries;
using Monaco.Template.Application.Features.Image.Queries;
using Monaco.Template.Backend.Application.DTOs;
using Monaco.Template.Backend.Application.Features.File.Queries;
using Monaco.Template.Backend.Application.Features.Image.Queries;
using MediatR;
#if (!disableAuth)
using Microsoft.AspNetCore.Authorization;
#endif
using Microsoft.AspNetCore.Mvc;
using System.Net;
using Monaco.Template.Common.Api.Application;
using Monaco.Template.Backend.Common.Api.Application;

namespace Monaco.Template.Api.Controllers
namespace Monaco.Template.Backend.Api.Controllers
{
[Route("api/v{apiVersion:apiVersion}/[controller]")]
[ApiController]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Monaco.Template.Backend.Api.DTOs;

public class CompanyCreateEditDto
{
public string? Name { get; set; }
public string? Email { get; set; }
public string? WebSiteUrl { get; set; }
public string? Street { get; set; }
public string? City { get; set; }
public string? County { get; set; }
public string? PostCode { get; set; }

public Guid? CountryId { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Monaco.Template.Application.Features.Company.Commands;
using Monaco.Template.Backend.Application.Features.Company.Commands;

namespace Monaco.Template.Api.DTOs.Extensions;
namespace Monaco.Template.Backend.Api.DTOs.Extensions;

public static class CompanyExtensions
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,16 @@
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="7.0.1" />
<PackageReference Include="Serilog.AspNetCore" Version="6.1.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" />
<PackageReference Include="Serilog.Sinks.ApplicationInsights" Version="4.0.0" />
<PackageReference Include="Serilog.Sinks.Debug" Version="2.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Monaco.Template.Application.Infrastructure.Migrations\Monaco.Template.Application.Infrastructure.Migrations.csproj" />
<ProjectReference Include="..\Monaco.Template.Application\Monaco.Template.Application.csproj" />
<ProjectReference Include="..\Monaco.Template.Common.Api.Application\Monaco.Template.Common.Api.Application.csproj" />
<ProjectReference Include="..\Monaco.Template.Common.Api\Monaco.Template.Common.Api.csproj" />
<ProjectReference Include="..\Monaco.Template.Common.Serilog\Monaco.Template.Common.Serilog.csproj" />
<ProjectReference Include="..\Monaco.Template.Backend.Application.Infrastructure.Migrations\Monaco.Template.Backend.Application.Infrastructure.Migrations.csproj" />
<ProjectReference Include="..\Monaco.Template.Backend.Application\Monaco.Template.Backend.Application.csproj" />
<ProjectReference Include="..\Monaco.Template.Backend.Common.Api.Application\Monaco.Template.Backend.Common.Api.Application.csproj" />
<ProjectReference Include="..\Monaco.Template.Backend.Common.Api\Monaco.Template.Backend.Common.Api.csproj" />
<ProjectReference Include="..\Monaco.Template.Backend.Common.Serilog\Monaco.Template.Backend.Common.Serilog.csproj" />
</ItemGroup>

</Project>
Loading

0 comments on commit 8d68452

Please sign in to comment.