diff --git a/.template.config/template.json b/.template.config/template.json index 6212f5f6a..bcd4c09fb 100644 --- a/.template.config/template.json +++ b/.template.config/template.json @@ -53,6 +53,7 @@ "**/[Bb]in/**", "**/[Oo]bj/**", ".template.config/**/*", + "templates/**/*", ".vs/**/*", "**/*.filelist", "**/*.user", diff --git a/CleanArchitecture.nuspec b/CleanArchitecture.nuspec index 40e597b84..3a4152625 100644 --- a/CleanArchitecture.nuspec +++ b/CleanArchitecture.nuspec @@ -3,7 +3,7 @@ Clean.Architecture.Solution.Template - 8.0.0-preview.5.1 + 8.0.0-preview.5.2 Clean Architecture Solution Template JasonTaylorDev Clean Architecture Solution Template for .NET 8. @@ -11,7 +11,7 @@ A Clean Architecture Solution Template for creating a Single-Page Application (SPA) with ASP.NET Core. - Added support for React. + Added item template for creating use cases (commands and queries) https://github.com/JasonTaylorDev/CleanArchitecture diff --git a/README.md b/README.md index 70b9d77bd..c62c6fb25 100644 --- a/README.md +++ b/README.md @@ -19,14 +19,39 @@ The goal of this template is to provide a straightforward and efficient approach * [FluentValidation](https://fluentvalidation.net/) * [NUnit](https://nunit.org/), [FluentAssertions](https://fluentassertions.com/), [Moq](https://github.com/moq) & [Respawn](https://github.com/jbogard/Respawn) +## Dependencies +The template depends on the latest versions of: + +* [.NET 8 SDK](https://dotnet.microsoft.com/download/dotnet/8.0) +* [Node.js LTS](https://nodejs.org/en/) + ## Getting Started -The easiest way to get started is to install the [.NET template](https://www.nuget.org/packages/Clean.Architecture.Solution.Template) and run `dotnet new ca-sln`: +The easiest way to get started is to install the [.NET template](https://www.nuget.org/packages/Clean.Architecture.Solution.Template): +``` +dotnet new install Clean.Architecture.Solution.Template::8.0.0-preview.5.2 +```` + +Once installed, create a new solution using the template: +``` +dotnet new ca-sln -c --output +``` -1. Install the latest versions of [.NET 8 SDK](https://dotnet.microsoft.com/download/dotnet/8.0) and [Node.js LTS](https://nodejs.org/en/) -2. Run `dotnet new install Clean.Architecture.Solution.Template::8.0.0-preview.5.1` to install the .NET template -4. Run `dotnet new ca-sln -c --output ` to create a new project -5. Navigate to `YourProjectName/src/WebUI` and launch the project using `dotnet run` +The above command creates a SPA with Angular or React on ASP.NET Core. Start the application by navigating to `./src/WebUI` and running: +``` +dotnet run +``` + +Create use cases (commands or queries) by navigating to `./src/Application`, and running: +``` +dotnet new ca-usecase --feature TodoLists --name CreateTodoList --useCaseType command --returnType int +``` + +To learn more, run the following command: + +``` +dotnet new ca-usecase --help +``` ## Database diff --git a/templates/ca-use-case/.template.config/icon.png b/templates/ca-use-case/.template.config/icon.png new file mode 100644 index 000000000..68e954e1d Binary files /dev/null and b/templates/ca-use-case/.template.config/icon.png differ diff --git a/templates/ca-use-case/.template.config/template.json b/templates/ca-use-case/.template.config/template.json new file mode 100644 index 000000000..2006c8983 --- /dev/null +++ b/templates/ca-use-case/.template.config/template.json @@ -0,0 +1,78 @@ +{ + "$schema": "http://json.schemastore.org/template", + "author": "JasonTaylorDev", + "classifications": [ + "Clean Architecture" + ], + "name": "Clean Architecture Solution Use Case", + "description": "Create a new use case (query or command)", + "identity": "Clean.Architecture.Solution.UseCase.CSharp", + "groupIdentity": "Clean.Architecture.Solution.UseCase", + "shortName": "ca-usecase", + "tags": { + "language": "C#", + "type": "item" + }, + "sourceName": "CleanArchitectureUseCase", + "preferNameDirectory": false, + "symbols": { + "DefaultNamespace": { + "type": "bind", + "binding": "msbuild:RootNamespace", + "replaces": "CleanArchitecture.Application", + "defaultValue": "CleanArchitecture.Application" + }, + "featureName": { + "type": "parameter", + "datatype": "string", + "isRequired": true, + "replaces": "FeatureName", + "fileRename": "FeatureName" + }, + "useCaseType": { + "type": "parameter", + "datatype": "choice", + "isRequired": true, + "choices": [ + { + "choice": "command", + "description": "Create a new command" + }, + { + "choice": "query", + "description": "Create a new query" + } + ], + "description": "The type of use case to create" + }, + "createCommand": { + "type": "computed", + "value": "(useCaseType == \"command\")" + }, + "createQuery": { + "type": "computed", + "value": "(useCaseType == \"query\")" + }, + "returnType": { + "type": "parameter", + "datatype": "string", + "isRequired": false, + "replaces": "object", + "defaultValue": "object" + } + }, + "sources": [ + { + "modifiers": [ + { + "condition": "(createCommand)", + "exclude": [ "FeatureName/Queries/**/*" ] + }, + { + "condition": "(createQuery)", + "exclude": [ "FeatureName/Commands/**/*" ] + } + ] + } + ] +} \ No newline at end of file diff --git a/templates/ca-use-case/FeatureName/Commands/CleanArchitectureUseCase/CleanArchitectureUseCase.cs b/templates/ca-use-case/FeatureName/Commands/CleanArchitectureUseCase/CleanArchitectureUseCase.cs new file mode 100644 index 000000000..18226bed3 --- /dev/null +++ b/templates/ca-use-case/FeatureName/Commands/CleanArchitectureUseCase/CleanArchitectureUseCase.cs @@ -0,0 +1,29 @@ +using CleanArchitecture.Application.Common.Interfaces; + +namespace CleanArchitecture.Application.FeatureName.Commands.CleanArchitectureUseCase; + +public record CleanArchitectureUseCaseCommand : IRequest +{ +} + +public class CleanArchitectureUseCaseCommandValidator : AbstractValidator +{ + public CleanArchitectureUseCaseCommandValidator() + { + } +} + +public class CleanArchitectureUseCaseCommandHandler : IRequestHandler +{ + private readonly IApplicationDbContext _context; + + public CleanArchitectureUseCaseCommandHandler(IApplicationDbContext context) + { + _context = context; + } + + public async Task Handle(CleanArchitectureUseCaseCommand request, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } +} diff --git a/templates/ca-use-case/FeatureName/Queries/CleanArchitectureUseCase/CleanArchitectureUseCase.cs b/templates/ca-use-case/FeatureName/Queries/CleanArchitectureUseCase/CleanArchitectureUseCase.cs new file mode 100644 index 000000000..47470ec08 --- /dev/null +++ b/templates/ca-use-case/FeatureName/Queries/CleanArchitectureUseCase/CleanArchitectureUseCase.cs @@ -0,0 +1,29 @@ +using CleanArchitecture.Application.Common.Interfaces; + +namespace CleanArchitecture.Application.FeatureName.Queries.CleanArchitectureUseCase; + +public record CleanArchitectureUseCaseQuery : IRequest +{ +} + +public class CleanArchitectureCommandCommandValidator : AbstractValidator +{ + public CleanArchitectureCommandCommandValidator() + { + } +} + +public class CleanArchitectureUseCaseQueryHandler : IRequestHandler +{ + private readonly IApplicationDbContext _context; + + public CleanArchitectureUseCaseQueryHandler(IApplicationDbContext context) + { + _context = context; + } + + public async Task Handle(CleanArchitectureUseCaseQuery request, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } +}