Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CHORE: Reorganize source files structure #36

Merged
merged 13 commits into from
Jan 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
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