Giter Club home page Giter Club logo

monaco's Introduction

Logo Monaco

Nuget version Nuget downloads License Release to NuGet

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 and here), 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.

The backend solution is based on the Vertical Slices 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.

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

Getting Started

Supported .NET version:

8.0

Installation

dotnet new install Monaco.Template

Uninstalling

dotnet new uninstall Monaco.Template

How to create a Monaco based solution

For generating a new backend solution, you can run the following command:

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)

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-backend-solution --help

(For more information about Monaco options please refer here)

Documentation

For more detailed documentation, please refer to our Wiki

Visual Studio support

From version 2.4.0 Monaco has stopped supporting Visual Studio for the template backend-solution-template and it won't show up on its templates list until further notice due to the existing issues in VS to generate projects with this kind of template.

The experience offered on Visual Studio was subpar as the output generated from within the IDE excluded all the solution folders that Monaco intended to create by default and the file system folders structure was also generated incorrectly; while everything works as expected when ran from the CLI. Because of all this, we decided to leave the CLI as the only valid alternative for using Monaco as it's the only one that guarantees a correct structure both in the file system and in the solution folders generated.

Contributing

If you want to contribute, we are currently accepting PRs and/or proposals/discussions in the issue tracker.

monaco's People

Contributors

cesard avatar dependabot[bot] avatar frkn2076 avatar gonzo345 avatar matthewtoghill avatar ulisesgascon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

monaco's Issues

Individual files templates

Create templates for the following types of individual files

  • Command feature file
    • Command (with / without return type)
    • Validator (with / without ID)
    • CommandHandler
  • Query feature file
    • Query (generic / paged / by ID)
    • QueryHandler

FEATURE: Include .NET Aspire in Backend solution

Detailed Description

Include .NET Aspire orchestration and components as part of the Backend solution.

Context

Since we want to include multiple other features for making Monaco a cloud-ready app template (like #26, #21 or #22), leveraging something like .NET Aspire can significantly help orchestrate multiple services and also make easier to include some other features like adding health-checks and telemetry, which will greatly improve the monitoring and debugging of such application.
.NET Aspire is also receiving in the short term the possibility to link extra-solution projects, which will greatly help and simplify orchestrate projects from different solutions (and possibly repos, through the use of submodules) that would otherwise could require much more manual work and simplify developing microservices-based applications.

Possible Implementation

This could be implemented after implementing the forementioned work in previous section.

FEATURE: Project template for Azure Function

Detailed Description

Create another project template on the solution of type Azure Function (isolated process) for setting up a timer-triggered function.

Context

The idea behind this is to include another type of project that could be required to use in a .NET backend solution, and to also serve as an example of how to implement it with Monaco's vision.

Possible Implementation

A possible implementation could be to use it as a sample scenario to remove files that have remained as temporary files for longer than 6 hs after being uploaded from the API.

FEATURE: Include a gRPC service project as alternative to REST API project

Detailed Description

Include a new project for implementing a gRPC service as interface for consuming Monaco's demo business as an alternative to the current REST API service project. This new project should be enabled by its own template flag just like the REST API and Worker Service ones.
Also, the YARP API Gateway implementation should leverage this to include the corresponding mappings to route from the external REST endpoints to the new gRPC service.
It is expected that the implementation of this gRPC service should be useful for microservices behind an API Gateway/Reverse Proxy and not to be directly exposed to the internet providing authentication in the same manner the REST API project is capable of.

Context

REST APIs are useful for communicating from browsers or for integrating with other external services, but when implementing several microservices interacting with each other or receiving requests from an API Gateway or Reverse Proxy (like YARP in Monaco's case), REST API generates an extra overhead that may increase latency and network traffic: transferring JSON, parsing it, etc.
Since gRPC uses a binary format that is much more reduced than JSON, it helps reduce the traffic and latency only by not having to transfer larger amounts of data in each request as well as the need of parsing human readable text, improving a lot the scenario. But there's also several more features provided by the protocol that will improve the overall communication.

Possible Implementation

The new gRPC service should be enabled by a flag --gRPC that, in a first version, should not include authentication. This flag should also enable the mappings in the API Gateway (if enabled and rendered) so the external endpoints can be redirected directly to the gRPC service accordingly.

BUG: Compile error in solution generated using "disableAuth" option

Description

Using the "disableAuth" option when generating a solution from the template results in a compiling error because it does not remove all references to "Auth" in Monaco.Template.Backend.Api

Expected Behavior

Line 8 in Monaco.Template.Backend.Api ->Program.cs should be also removed when generating the solution

Actual Behavior

Compiling error

Possible Fix

Just move the disableAuth flag one line up

Steps to Reproduce

  1. Generate a solution using "disableAuth" option
  2. Build the solution

Upgrade to NET 7

Upgrade framework used to NET 7 and upgrade related dependencies accordingly.

FEATURE: Dockerization

Detailed Description

Include Docker configuration in the solution for the corresponding projects.

Context

This will help to offer the possibility of support containers such as Docker straight from the solution generation, without the developers having to implement it on their own afterwards.
It might also be very useful for later implementing the .NET Aspire integration from #55.

Possible Implementation

We can leverage the newly added native support for Containers by the .NET team: https://github.com/dotnet/sdk-container-builds/blob/main/README.md.

FEATURE: Include a Products entity with pictures for sampling anonymous endpoints and downloading

Detailed Description

Just as right now the Backend project offers a sample of a Companies CRUD, it would be interesting to include a sample of how files can be related to entities in order to provide a more concrete demonstration, as right now the --fileSupport switch doesn't offer any of this and only a separate domain entities with no relationship with anything.

Context

This should help to provide some better context and example of how files can be linked to entities and how Monaco envisions this to be implemented, serving -just like the Companies CRUD- as a reference for developing similar stuff.

Possible Implementation

Provide a Products CRUD that include at least a picture (or more) for a better practical demonstration on how to handle the files being related to other entities.
The Products GET endpoints can be set with Anonymous access as that could give place to a frontend displaying content for the public without having to go through authentication.

REFACTOR: Replace Dawn.Guard with Throw and refactor domain validations

Detailed Description

Replace argument validation library Dawn.Guard with Throw library. Refactor corresponding domain validations and use the occasion to improve them.

Context

Because the library Dawn.Guard has been abandoned by its author, it became required to find an alternative that allows to do something similar and that also gets good maintenance support from its author.
For this purpose, the library Throw from Amichai Mantinband is a very good candidate since it's been conceived taking Dawn.Guard as reference but also allows some extra features.
It was considered the use of GuardClauses, but its syntax and features made it less appealing than Throw.
Also, since it will be needed to refactor all the current domain validations, we can use the occasion to improve them and add some more of them on places where there should be some validations.
This will also require to refactor unit tests and improve them to cover different scenarios that were currently not taken into consideration.

Replace System.Drawing implementation

Replace the System.Drawing dependency on the FileService implementation for allow better multi-platform compatibility. Good candidate for replacement: SkiaSharp.

REFACTOR: Backend template flags rework

Detailed Description

Refactor some of the current Backend template flags to provide a more concise representation of their usage and include some extra flags to allow more granular control over the projects generated within the solution.

Context

Some of the current Backend template flags are useful but their naming and usage may lead to some confusions and misunderstandings, so it will be helpful to refactor them a bit to provide a more concise representation of their usage. Also, it's a good opportunity to include some extra flags to provide more switches over certain projects within the solution.

Possible Implementation

Each of them can be refactored as follows:

  • excludeCommon
    • New name: commonLibraries
    • Default: true
  • excludeFilesSupport
    • New name: filesSupport
    • Default: true
  • massTransitIntegration
    • Unchanged
  • apiGateway
    • Unchanged
  • disableAuth
    • New name: auth
    • Default: true
  • workerService
    • Unchanged
  • keycloakConfig
    • Unchanged
  • keycloakRealm
    • Unchanged
  • New flag:
    • apiService
    • Default: true
    • Enables/Disables the API service project
  • New flag:
    • tests
    • Default: true
    • Enables/Disables all test projects

FEATURE: Replace Controllers with Minimal APIs implementation

Detailed Description

Replace the current Controllers implementation with the newer Minimal APIs mechanism.

Context

The Minimal APIs have much less dependencies and provide improved performance against the Controllers. Also, they are flexible enough to be used in very small API projects, which make it ideal for the default implementation of REST APIs in Monaco.

Possible Implementation

I would think towards grouping the APIs by their declared resources, similarly to what we do nowadays with routing in Controllers, separating them in different files.

Create generic handler for status 500 errors

When as a result of a request to the backend the response is a status 500, there should be a cross-app mechanism to catch this, log it properly and display a generic (yet user friendly) error to the user, letting them know that there's been an error when calling the server.

FEATURE: Change implementation of ValueObject to ComplexTypes

Detailed Description

Change the implementation of ValueObject to leverage EF Core 8's ComplexTypes and Records.

Context

With the release of EF Core 8, ComplexTypes have been introduced which help leverage ValueObjects much better and properly than with the current implementation: https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/whatsnew#value-objects-using-complex-types.
ComplexTypes allow to handle the ValueObjects without masking an entity behind scenes so one can handle the same instance and assign it to multiple entities without DbContext to break do to multiple entity being tracked multiple times. Also, it allows to work with Records, which are a much better type to work with for ValueObjects without having to resort to a class overriding its base methods.

Possible Implementation

Switching ValueObject class by implementing Records and replacing OwnsOne by ComplexProperty in the parent entities.

Implementation blocked by issue: dotnet/efcore#31245

FEATURE: Project template for WorkerService

Detailed Description

Create a new project template for a Worker Service on the solution.

Context

The backend is not only comprised by APIs; many times there's need to run unattended services that perform some processing in the background without direct interaction with the users. These services are also useful for offloading some responsibilities from APIs, decoupling responsibilities and allow for better balancing of the workload.

Possible Implementation

Create a Worker Service that hosts a MassTransit consumer of a message emitted by the API once a Product gets created to serve as a sample of how to configure this scenario.
Consumer can do as little as just log the operation for sample purposes.
Project should have its own flag and include all the MassTransit boilerplate depending on the respective flag.

REFACTOR: CommandResult simplification and optimization

Detailed Description

Simplify and optimize the CommandResult implementation to make it less verbose and more descriptive.

Context

Right now the implementation of the CommandResults uses an interface that makes little sense since it isn't leveraged for anything. Also, the CommandResult has multiple overloads of its constructor that make it a bit cumbersome to use.

Blazor WebAssembly template: Authentication implementation

Add Authentication to login against something similar the monaco-solution template uses (a generic OpenId Connect identity provider like Keycloak).
App should display current logged in user in the main layout and allow the user to logout or display their details.

FEATURE: Upgrade .NET version used to v8.0.

Detailed Description

Upgrade the .NET version used by Monaco to the latest version: v8.0.

Context

In order to leverage the new .NET 8 capabilities and to provide support for it for new projects generated with Monaco, it becomes necessary to upgrade all the projects to target the new version as well as upgrade the existing dependencies.

FEATURE: Add architecture tests to the Backend solution

Detailed Description

Add to the already existing tests a new type for testing the architecture of the solution.

Context

This should help keeping existing conventions and structure and allow the developers of the derived solutions to know if some new component is breaking some rule or how to keep naming/structuring things while the're added.

Possible Implementation

BUG: Creating a project without Files Support does not exclude FileServiceTests

Description

When creating a new project from the template if the 'Include file support and structure' flag is not ticked then the template creates the project including the file: FileServiceTests.cs within the namespace Monaco.Template.Backend.Application.Tests.Services. The application fails to build whilst this file is present as the files it relates to have been correctly excluded from the project creation.

Expected Behavior

The FileServiceTests.cs file should be excluded when the 'Include file support and structure' flag is set to false.

Actual Behavior

The FileServiceTests.cs file is included when the 'Include file support and structure' flag is set to false.

Possible Fix

Update template.json to exclude the file on the appropriate condition.

Steps to Reproduce

  1. Create a new project using the template with the 'Include file support and structure' flag is set to false
  2. Try to build the application

.NET MAUI template: Authentication implementation

Add Authentication to login against something similar the monaco-solution template uses (a generic OpenId Connect identity provider like Keycloak).
App should display current logged in user in the main layout and allow the user to logout or display their details.

Create generic handler for status 500 errors

When as a result of a request to the backend the response is a status 500, there should be a cross-app mechanism to catch this, log it properly and display a generic (yet user friendly) error to the user, letting them know that there's been an error when calling the server.

Can't properly filter by nullable primitive datatypes

Recently found an issue where an Entity offering filtering by nullable properties is not being applied correctly.

The ValidateDateType method seems that isn't properly detecting the provided type as valid.

I remember this PR was supposed to fix this but seems that it just works with explicit string?

Tried different workarounds and got it working with Guid? but the workaround made it failing with other nullable types

Project template for .NET MAUI app

Include a skeleton project template (standalone, not included in the monaco-solution template) for a .NET MAUI client application that runs at least in Windows and Android platforms.

Update Keycloak config for client roles rather than realm roles

Detailed Description

Update Keycloak built-in configuration to include default roles as the API client roles rather than as realm roles.
So far, Monaco's configuration of Keycloak was based on realm's roles. This is ok for a very simple scenario, but in other more realistic scenarios it could happen that

Context

The default configuration so far was ok for very simple scenarios where only 1 system (as the Monaco generated API) exists because a realm role would suffice, but if we're aiming to a bit more complex scenario where there could be multiple systems with similar roles but with different permissions each, then it would make it too cumbersome to properly assign such permissions to users.
For example: a user could be an Admin on SystemA but perhaps shouldn't be an Admin but rather a Supervisor on SystemB.
Implementing client roles is the correct way to configure Keycloak for this purpose.

Reorganize source folder structure for multiple templates

We need to reorganize the source folder structure to be able to support multiple templates for being installed by the same Nuget package.
This will be required if we want to go ahead and use the same Nuget package to install the multiple templates that we're expecting to generate, like individual files from #27, or projects that are meant to be separated from the backend like #12 and #14 (which will eventually end up being totally separate solutions in order to decouple those web and mobile frontends from the backend generated by monaco-solution).

FEATURE: Single file commands/queries

Detailed Description

To convert the current structure that Monaco currently has about Commands/Validators and Queries folders to one where each Command and Query are placed in the same file with their corresponding handlers.
This is oriented to decompress the bloating that sometimes might affect the Commands/Queries Handlers files when there are too many commmands/queries for an entity.

Context

In order to better group together queries with their handlers and commands with their respective validators and handlers, it could be better to group each of them together in a single file, to further simplify the navigation between a query and its handler, the same as with a command with its respective validator and handler.
This should make it simpler to navigate through the structure, would align to the vertical slicing more properly, simplify handlers files that sometimes get too bloated when there are too many commands/queries, and would also simplify the testing, aligning it, as well, to the vertical slicing concept as all the tests related to a same slice would be easier to group themselves instead of having a big handlers test class that will contain all tests for all the handlers of a same entity as we currently have.
A con to this approach is that some of the shared code between some slices won't be contained in the same handlers class, within reach of all the different handlers (same would occur with the tests); but I think the solution for this can be as easy to create more extensions and static classes/methods in an "Extensions" folder to contain all the shared code there.

Possible Implementation

To use it as an example, the current folder from Application.Features.Company could be structured like this:

  • Companies (folder)
    • Extensions (folder)
      • [ Any extra extension classes/files that can be used for sharing code between slices ]
    • CreateCompany.cs
      • CreateCompany (class)
        • Command (nested class)
        • Validator (nested class)
        • Handler (nested class)
    • EditCompany.cs
      • EditCompany (class)
        • Command (nested class)
        • Validator (nested class)
        • Handler (nested class)
    • DeleteCompany.cs
      • DeleteCompany (class)
        • Command (nested class)
        • Validator (nested class)
        • Handler (nested class)
    • GetCompaniesPage.cs
      • GetCompaniesPage (class)
        • Query (nested class)
        • Handler (nested class)
    • GetCompanyById
      • GetCompanyById (class)
        • Query (nested class)
        • Handler (nested class)

Each of the features (Create/Edit/Delete Company and Get Page/ById) would be separated into different files with a class that will nest 3/2 other classes (depending on whether it's a command or query), and each of these nested classes would be the specific command/query, its handler and (in the case of the commands) its validator.

SignalR integration

Include an integration and options for configuring SignalR in the solution.

REFACTOR: Migrate Polly v7 Policies into v8 ResiliencePipeline

Detailed Description

Despite having upgraded Polly from v7 to v8 in the dependencies, the upgrade of its implementation has not yet been performed, so this issue is about tracking the work to perform that.

Context

This will allow to be in line with the new Polly APIs and ResiliencePipelines that are much better and easier to use than the previous Policies.

BUG: Missing SkiaSharp dependency when running on Linux.

Description

When trying to upload a file while the app is running on Linux, the following error is thrown:

Error Message:
   System.TypeInitializationException : The type initializer for 'SkiaSharp.SKData' threw an exception.
---- System.DllNotFoundException : Unable to load shared library 'libSkiaSharp' or one of its dependencies. In order to help diagnose loading problems, consider using a tool like strace. If you're using glibc, consider setting the LD_DEBUG environment variable: 
/usr/share/dotnet/shared/Microsoft.NETCore.App/8.0.1/libSkiaSharp.so: cannot open shared object file: No such file or directory
/home/vsts/work/1/s/src/MonacoApp.Application.Tests/bin/Release/net8.0/libSkiaSharp.so: cannot open shared object file: No such file or directory

Expected Behavior

The file should be uploaded correctly without any issues.

Actual Behavior

The upload is aborted due to the forementioned exception being thrown.

Possible Fix

Adding an extra dependency: SkiaSharp.NativeAssets.Linux.NoDependencies should fix it.

Steps to Reproduce

  1. Generate a new solution with files support.
  2. Run the solution on Linux (either directly or with a container on Linux).
  3. Try to upload an image with the endpoint POST api/v1/Files
  4. An error will be thrown as explained above.

Context

Trying to upload files while running the app on a Linux OS.

Your Environment

  • Version used: 2.3
  • Operating System and version (desktop or mobile): Linux

FEATURE: Implement Feature Flags

Detailed Description

Perform the implementation of Feature Flags with the use of the Microsoft.FeatureManagement libraries.

Context

Because many projects release strategy is based on the trunk-based development, it is especially important to be able to enable/disable new/existing features in order to be able to perform A/B testing and prevent new changes from impacting the entire user base once these changes are released into Production. For this, the Feature Flags implementation is a very useful tool to allow the development team to progressively enable/disable such features so they can be tested on a reduced number of users without affecting all of them.

Possible Implementation

A starting point could be like the one displayed in the following article: https://timdeschryver.dev/blog/feature-flags-in-net-from-simple-to-more-advanced.
The idea is to be able to abstract the implementation so later the flags can be implemented with either Azure App Configuration, ConfigCat or any other similar service.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.