Last active
December 29, 2025 11:18
-
-
Save sheepla/74c643b20525f6d9f8760579164d5731 to your computer and use it in GitHub Desktop.
Creating DDD-like vertical-slice architecture project for ASP.NET Core + EF Core backend and Vite + React + shadcn/ui frontend
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/sh | |
| # Application specific configuration | |
| SOLUTION_NAME="LibrarySystem" | |
| FEATURES=("Users" "Books" "Lending" "Reserving") | |
| API_PROJECT_NAME="${SOLUTION_NAME}.Presentaion.API" | |
| DOMAIN_PROJECT_NAME="${SOLUTION_NAME}.Domain" | |
| APPLICATION_PROJECT_NAME="${SOLUTION_NAME}.Application" | |
| DATABASE_PROJECT_NAME="${SOLUTION_NAME}.Infrastructure.Database" | |
| API_PROJECT_DIR="src/${API_PROJECT_NAME}" | |
| DOMAIN_PROJECT_DIR="src/${DOMAIN_PROJECT_NAME}" | |
| APPLICATION_PROJECT_DIR="src/${APPLICATION_PROJECT_NAME}" | |
| DATABASE_PROJECT_DIR="src/${DATABASE_PROJECT_NAME}" | |
| mkdir src | |
| mkdir tests | |
| echo "Creating API layer project..." | |
| dotnet new webapi -o "${API_PROJECT_DIR}" | |
| echo "Creating domain layer project..." | |
| dotnet new classlib -o "${DOMAIN_PROJECT_DIR}" | |
| rm "${DOMAIN_PROJECT_DIR}/Class1.cs" | |
| echo "Creating application layer project..." | |
| dotnet new classlib -o "${APPLICATION_PROJECT_DIR}" | |
| echo "Creating database layer project..." | |
| dotnet new classlib -o "${DATABASE_PROJECT_DIR}" | |
| rm "${DATABASE_PROJECT_DIR}/Class1.cs" | |
| echo "Creating solution..." | |
| dotnet new sln # Create an empty '*.sln' file | |
| dotnet sln migrate # Migrate from '*.sln' to '*.slnx' (a new simplified format for .NET solution file) | |
| rm "${SOLUTION_NAME}.sln" # Remove old '*.sln' file | |
| # Add '*.csproj' references | |
| dotnet sln add "${API_PROJECT_DIR}" | |
| dotnet sln add "${DOMAIN_PROJECT_DIR}" | |
| dotnet sln add "${APPLICATION_PROJECT_DIR}" | |
| dotnet sln add "${DATABASE_PROJECT_DIR}" | |
| # Add each layers references | |
| dotnet add "${API_PROJECT_DIR}" reference "${DOMAIN_PROJECT_DIR}" # To refer domain models | |
| dotnet add "${API_PROJECT_DIR}" reference "${APPLICATION_PROJECT_DIR}" # To call application services | |
| dotnet add "${API_PROJECT_DIR}" reference "${DATABASE_PROJECT_DIR}" # Just for DI | |
| dotnet add "${APPLICATION_PROJECT_DIR}" reference "${DOMAIN_PROJECT_DIR}" # To refer domain models | |
| dotnet add "${DATABASE_PROJECT_DIR}" reference "${DOMAIN_PROJECT_DIR}" # To refer domain models | |
| echo "Installing dependencies (libraries)..." | |
| # Compile-time generate type-safe object mapper (alternative for AutoMapper) | |
| dotnet add "${API_PROJECT_DIR}" package Riok.Mapperly | |
| # OpenAPI document generator | |
| dotnet add "${API_PROJECT_DIR}" package Swashbuckle.AspNetCore | |
| # Alternative UI for Swagger UI | |
| dotnet add "${API_PROJECT_DIR}" package Scalar.AspNetCore | |
| # Compile-time generate type-safe object mapper (alternative for AutoMapper) | |
| dotnet add "${APPLICATION_PROJECT_DIR}" package Riok.Mapperly | |
| # Error handling library with 'Result' type for .NET | |
| dotnet add "${APPLICATION_PROJECT_DIR}" package FluentResults | |
| # EFCore - ORM framework | |
| dotnet add "${DATABASE_PROJECT_DIR}" package Microsoft.EntityFrameworkCore | |
| # PostgreSQL | |
| dotnet add "${DATABASE_PROJECT_DIR}" package Npgsql.EntityFrameworkCore.PostgreSQL | |
| # EFCore tools | |
| dotnet add "${DATABASE_PROJECT_DIR}" package Microsoft.EntityFrameworkCore.Tools | |
| echo "Installing dependencies (tools)..." | |
| dotnet tool install dotnet-ef | |
| echo "Creating features dirs" | |
| mkdir -p "${API_PROJECT_DIR}/Abstractions" | |
| for feature in "${FEATURES[@]}" | |
| do | |
| mkdir -p "${API_PROJECT_DIR}/Features/${feature}" | |
| done | |
| mkdir -p "${DOMAIN_PROJECT_DIR}/Abstractions" | |
| for feature in "${FEATURES[@]}" | |
| do | |
| mkdir -p "${DOMAIN_PROJECT_DIR}/Features/${feature}" | |
| done | |
| mkdir -p "${APPLICATION_PROJECT_DIR}/Abstractions" | |
| for feature in "${FEATURES[@]}" | |
| do | |
| mkdir -p "${APPLICATION_PROJECT_DIR}/Features/${feature}" | |
| done | |
| mkdir -p "${DATABASE_PROJECT_DIR}/Abstractions" | |
| for feature in "${FEATURES[@]}" | |
| do | |
| mkdir -p "${DATABASE_PROJECT_DIR}/Features/${feature}" | |
| done | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/sh | |
| PROJECT_DIR="frontend" | |
| pnpm create vite@latest "${PROJECT_DIR}" --template react-swc-ts --no-interactive | |
| cd "${PROJECT_DIR}" | |
| echo "Installing dependencies..." | |
| pnpm install | |
| echo "Initializing TailwindCSS..." | |
| pnpm add tailwindcss @tailwindcss/vite | |
| cat << EOF > src/index.css | |
| @import "tailwindcss"; | |
| EOF | |
| echo "Configuring TypeScript..." | |
| pnpm add -D @types/node | |
| cat << EOF > tsconfig.json | |
| { | |
| "files": [], | |
| "references": [ | |
| { | |
| "path": "./tsconfig.app.json" | |
| }, | |
| { | |
| "path": "./tsconfig.node.json" | |
| } | |
| ], | |
| /* import-alias for shadcn/ui */ | |
| "compilerOptions": { | |
| "baseUrl": ".", | |
| "paths": { | |
| "@/*": ["./src/*"] | |
| } | |
| } | |
| } | |
| EOF | |
| cat << EOF > tsconfig.app.json | |
| { | |
| "compilerOptions": { | |
| "ignoreDeprecations": "6.0", | |
| "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", | |
| "target": "ES2022", | |
| "useDefineForClassFields": true, | |
| "lib": [ | |
| "ES2022", | |
| "DOM", | |
| "DOM.Iterable" | |
| ], | |
| "module": "ESNext", | |
| "types": [ | |
| "vite/client" | |
| ], | |
| "skipLibCheck": true, | |
| /* import-alias for shadcn/ui */ | |
| "baseUrl": "./", | |
| "paths": { | |
| "@/*": [ | |
| "./src/*" | |
| ] | |
| }, | |
| /* Bundler mode */ | |
| "moduleResolution": "bundler", | |
| "allowImportingTsExtensions": true, | |
| "verbatimModuleSyntax": true, | |
| "moduleDetection": "force", | |
| "noEmit": true, | |
| "jsx": "react-jsx", | |
| /* Linting */ | |
| "strict": true, | |
| "noUnusedLocals": true, | |
| "noUnusedParameters": true, | |
| "erasableSyntaxOnly": true, | |
| "noFallthroughCasesInSwitch": true, | |
| "noUncheckedSideEffectImports": true | |
| }, | |
| "include": [ | |
| "src" | |
| ] | |
| } | |
| EOF | |
| echo "Configuring Vite..." | |
| pnpm add -D @vitejs/plugin-react | |
| cat << EOF > vite.config.ts | |
| import path from "path" | |
| import tailwindcss from "@tailwindcss/vite" | |
| import react from "@vitejs/plugin-react" | |
| import { defineConfig } from "vite" | |
| // https://vite.dev/config/ | |
| export default defineConfig({ | |
| plugins: [react(), tailwindcss()], | |
| resolve: { | |
| alias: { | |
| "@": path.resolve(__dirname, "./src"), | |
| }, | |
| }, | |
| server: { | |
| proxy: { | |
| '/api': { | |
| target: 'http://localhost:5000', // TODO: Fix with the actual backend server URL | |
| changeOrigin: true, | |
| secure: false, | |
| } | |
| } | |
| } | |
| }) | |
| EOF | |
| echo "Initializing shadcn/ui CLI..." | |
| pnpm dlx shadcn@latest init --base-color neutral | |
| pnpm dlx shadcn@latest add button | |
| echo "Initializing shadcn/ui sample component..." | |
| cat << EOF > src/App.tsx | |
| import { useState } from 'react' | |
| import { Button } from '@/components/ui/button' | |
| function App() { | |
| const [count, setCount] = useState(0) | |
| const handleClick = () => { | |
| setCount(count + 1) | |
| } | |
| return ( | |
| <div> | |
| <div className="flex min-h-svh flex-col items-center justify-center"> | |
| <Button onClick={handleClick}>Count: {count}</Button> | |
| </div> | |
| </div> | |
| ) | |
| } | |
| export default App | |
| EOF | |
| echo "Creating project dirs..." | |
| mkdir -p src/shared | |
| mkdir -p src/api | |
| mkdir -p src/features | |
| echo "Creating OpenAPI dir..." | |
| mkdir api | |
| echo "Removing unnecessary assets..." | |
| rm src/assets/react.svg | |
| rm public/vite.svg | |
| cd .. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment