[{"data":1,"prerenderedAt":1277},["ShallowReactive",2],{"docs-navigation":3,"doc-\u002Fdev\u002Fcsharp\u002Fproject-structure":229,"surround-\u002Fdev\u002Fcsharp\u002Fproject-structure":1076,"notes-index":1081},[4,88,171,182,192,203,218],{"title":5,"path":6,"stem":7,"children":8},"Dev","\u002Fdev","1.dev",[9,12,26,36,50,56,78],{"title":10,"path":6,"stem":11},"Development","1.dev\u002Findex",{"title":13,"path":14,"stem":15,"children":16},"Laravel","\u002Fdev\u002Flaravel","1.dev\u002F1.laravel\u002Findex",[17,18,22],{"title":13,"path":14,"stem":15},{"title":19,"path":20,"stem":21},"Eloquent Relationships","\u002Fdev\u002Flaravel\u002Feloquent-relationships","1.dev\u002F1.laravel\u002F1.eloquent-relationships",{"title":23,"path":24,"stem":25},"Laravel Homestead","\u002Fdev\u002Flaravel\u002Flaravel-homestead","1.dev\u002F1.laravel\u002F2.laravel-homestead",{"title":27,"path":28,"stem":29,"children":30},"Bash","\u002Fdev\u002Fbash","1.dev\u002F13.bash\u002Findex",[31,32],{"title":27,"path":28,"stem":29},{"title":33,"path":34,"stem":35},"My Bash RC","\u002Fdev\u002Fbash\u002Fbash-rc","1.dev\u002F13.bash\u002F2.bash-rc",{"title":37,"path":38,"stem":39,"children":40},"Clean Code","\u002Fdev\u002Fclean-code","1.dev\u002F15.clean-code\u002Findex",[41,42,46],{"title":37,"path":38,"stem":39},{"title":43,"path":44,"stem":45},"Naming Things","\u002Fdev\u002Fclean-code\u002Fnaming-things","1.dev\u002F15.clean-code\u002F1.naming-things",{"title":47,"path":48,"stem":49},"Services Return, Callers Present","\u002Fdev\u002Fclean-code\u002Fservices-return-callers-present","1.dev\u002F15.clean-code\u002F2.services-return-callers-present",{"title":51,"path":52,"stem":53,"children":54},"AI Prompting","\u002Fdev\u002Fai-prompting","1.dev\u002F17.ai-prompting\u002Findex",[55],{"title":51,"path":52,"stem":53},{"title":57,"path":58,"stem":59,"children":60},"C#","\u002Fdev\u002Fcsharp","1.dev\u002F2.csharp\u002Findex",[61,62,66,70,74],{"title":57,"path":58,"stem":59},{"title":63,"path":64,"stem":65},"C# Basics","\u002Fdev\u002Fcsharp\u002Fcsharp-basics","1.dev\u002F2.csharp\u002F1.csharp-basics",{"title":67,"path":68,"stem":69},"Classes & Models","\u002Fdev\u002Fcsharp\u002Fclasses-and-models","1.dev\u002F2.csharp\u002F2.classes-and-models",{"title":71,"path":72,"stem":73},"Services & Helpers","\u002Fdev\u002Fcsharp\u002Fservices-and-helpers","1.dev\u002F2.csharp\u002F3.services-and-helpers",{"title":75,"path":76,"stem":77},"Project Structure","\u002Fdev\u002Fcsharp\u002Fproject-structure","1.dev\u002F2.csharp\u002F4.project-structure",{"title":79,"path":80,"stem":81,"children":82},"Git","\u002Fdev\u002Fgit","1.dev\u002F9.git\u002Findex",[83,84],{"title":79,"path":80,"stem":81},{"title":85,"path":86,"stem":87},"Git Cheat Sheet","\u002Fdev\u002Fgit\u002Fgit-cheat-sheet","1.dev\u002F9.git\u002F1.git-cheat-sheet",{"title":89,"path":90,"stem":91,"children":92},"Teaching","\u002Fteaching","2.teaching",[93,95],{"title":89,"path":90,"stem":94},"2.teaching\u002Findex",{"title":96,"path":97,"stem":98,"children":99},"AppsDev","\u002Fteaching\u002Fapps-dev","2.teaching\u002F1.apps-dev\u002Findex",[100,101,119,137,147,161],{"title":96,"path":97,"stem":98},{"title":102,"path":103,"stem":104,"children":105},"Lesson Plans","\u002Fteaching\u002Fapps-dev\u002Flesson-plans","2.teaching\u002F1.apps-dev\u002F1.lesson-plans\u002Findex",[106,107,111,115],{"title":102,"path":103,"stem":104},{"title":108,"path":109,"stem":110},"Coding with AI","\u002Fteaching\u002Fapps-dev\u002Flesson-plans\u002Fcoding-with-ai","2.teaching\u002F1.apps-dev\u002F1.lesson-plans\u002F1.coding-with-ai",{"title":112,"path":113,"stem":114},"Coding with AI: Prompts & Reading JavaScript","\u002Fteaching\u002Fapps-dev\u002Flesson-plans\u002Fprompts-and-reading-js","2.teaching\u002F1.apps-dev\u002F1.lesson-plans\u002F2.prompts-and-reading-js",{"title":116,"path":117,"stem":118},"JavaScript for Beginners","\u002Fteaching\u002Fapps-dev\u002Flesson-plans\u002Fjavascript-for-beginners","2.teaching\u002F1.apps-dev\u002F1.lesson-plans\u002F3.javascript-for-beginners",{"title":120,"path":121,"stem":122,"children":123},"Activities","\u002Fteaching\u002Fapps-dev\u002Factivities","2.teaching\u002F1.apps-dev\u002F2.activities\u002Findex",[124,125,129,133],{"title":120,"path":121,"stem":122},{"title":126,"path":127,"stem":128},"Dynamic Portfolio Website","\u002Fteaching\u002Fapps-dev\u002Factivities\u002Fdynamic-portfolio-website","2.teaching\u002F1.apps-dev\u002F2.activities\u002F2.dynamic-portfolio-website",{"title":130,"path":131,"stem":132},"Mini Product Store","\u002Fteaching\u002Fapps-dev\u002Factivities\u002Fmini-product-store","2.teaching\u002F1.apps-dev\u002F2.activities\u002F3.mini-product-store",{"title":134,"path":135,"stem":136},"Semester Project","\u002Fteaching\u002Fapps-dev\u002Factivities\u002Fsemester-project","2.teaching\u002F1.apps-dev\u002F2.activities\u002F4.semester-project",{"title":138,"path":139,"stem":140,"children":141},"Exercises","\u002Fteaching\u002Fapps-dev\u002Fexercises","2.teaching\u002F1.apps-dev\u002F4.exercises\u002Findex",[142,143],{"title":138,"path":139,"stem":140},{"title":144,"path":145,"stem":146},"Read & Predict","\u002Fteaching\u002Fapps-dev\u002Fexercises\u002Fread-and-predict","2.teaching\u002F1.apps-dev\u002F4.exercises\u002F1.read-and-predict",{"title":148,"path":149,"stem":150,"children":151},"AI Prompts","\u002Fteaching\u002Fapps-dev\u002Fai-prompts","2.teaching\u002F1.apps-dev\u002F7.ai-prompts\u002Findex",[152,153,157],{"title":148,"path":149,"stem":150},{"title":154,"path":155,"stem":156},"Prompt Flow","\u002Fteaching\u002Fapps-dev\u002Fai-prompts\u002Fbasic-prompting","2.teaching\u002F1.apps-dev\u002F7.ai-prompts\u002F1.basic-prompting",{"title":158,"path":159,"stem":160},"Using OpenCode CLI Instead of Copy-Pasting from ChatGPT","\u002Fteaching\u002Fapps-dev\u002Fai-prompts\u002Fopencode-cli","2.teaching\u002F1.apps-dev\u002F7.ai-prompts\u002F2.opencode-cli",{"title":162,"path":163,"stem":164,"children":165},"Cheat Sheets","\u002Fteaching\u002Fapps-dev\u002Fcheat-sheets","2.teaching\u002F1.apps-dev\u002F8.cheat-sheets\u002Findex",[166,167],{"title":162,"path":163,"stem":164},{"title":168,"path":169,"stem":170},"How to Collaborate on GitHub","\u002Fteaching\u002Fapps-dev\u002Fcheat-sheets\u002Fgithub-collaboration","2.teaching\u002F1.apps-dev\u002F8.cheat-sheets\u002F1.github-collaboration",{"title":172,"path":173,"stem":174,"children":175},"Snippets","\u002Fsnippets","3.snippets",[176,178],{"title":172,"path":173,"stem":177},"3.snippets\u002Findex",{"title":179,"path":180,"stem":181},"Debounce and Throttle","\u002Fsnippets\u002Fdebounce-and-throttle","3.snippets\u002F1.debounce-and-throttle",{"title":162,"path":183,"stem":184,"children":185},"\u002Fcheat-sheets","4.cheat-sheets",[186,188],{"title":162,"path":183,"stem":187},"4.cheat-sheets\u002Findex",{"title":189,"path":190,"stem":191},"Vim Cheat Sheet","\u002Fcheat-sheets\u002Fvim-cheat-sheet","4.cheat-sheets\u002F1.vim-cheat-sheet",{"title":193,"path":194,"stem":195,"children":196},"Templates","\u002Ftemplates","5.templates",[197,199],{"title":193,"path":194,"stem":198},"5.templates\u002Findex",{"title":200,"path":201,"stem":202},"Pull Request Template","\u002Ftemplates\u002Fpull-request-template","5.templates\u002F1.pull-request-template",{"title":204,"path":205,"stem":206,"children":207},"Meta","\u002Fmeta","6.meta",[208,210,214],{"title":204,"path":205,"stem":209},"6.meta\u002Findex",{"title":211,"path":212,"stem":213},"Authoring Guide","\u002Fmeta\u002Fauthoring-guide","6.meta\u002F1.authoring-guide",{"title":215,"path":216,"stem":217},"Markdown Showcase","\u002Fmeta\u002Fmarkdown-showcase","6.meta\u002F2.markdown-showcase",{"title":219,"path":220,"stem":221,"children":222},"Troubleshooting","\u002Ftroubleshooting","7.troubleshooting",[223,225],{"title":219,"path":220,"stem":224},"7.troubleshooting\u002Findex",{"title":226,"path":227,"stem":228},"Fixing CORS Errors","\u002Ftroubleshooting\u002Fcors-errors","7.troubleshooting\u002F1.cors-errors",{"id":230,"title":75,"body":231,"category":1058,"createdAt":1059,"description":1060,"draft":1061,"extension":1062,"featured":1061,"keywords":1063,"links":1069,"meta":1070,"navigation":458,"path":76,"readingTime":306,"seo":1071,"stem":77,"tags":1072,"updatedAt":1059,"__hash__":1075},"docs\u002F1.dev\u002F2.csharp\u002F4.project-structure.md",{"type":232,"value":233,"toc":1049},"minimark",[234,238,243,259,343,349,374,378,390,398,406,409,426,482,532,569,573,587,924,928,1020,1024,1045],[235,236,237],"p",{},"The glue: how the files from the other notes become one program you can run.",[239,240,242],"h2",{"id":241},"create-and-run-a-project","Create and run a project",[235,244,245,246,250,251,254,255,258],{},"The ",[247,248,249],"code",{},"dotnet"," CLI is your ",[247,252,253],{},"composer"," + ",[247,256,257],{},"artisan"," combined:",[260,261,266],"pre",{"className":262,"code":263,"language":264,"meta":265,"style":265},"language-bash shiki shiki-themes material-theme-lighter vitesse-light vitesse-dark","dotnet new console -n MyApp   # create a console app in .\u002FMyApp\ncd MyApp\ndotnet run                    # build + run\ndotnet build                  # build only\ndotnet add package Newtonsoft.Json   # add a NuGet package (like composer require)\n","bash","",[247,267,268,294,304,315,326],{"__ignoreMap":265},[269,270,273,276,280,283,287,290],"span",{"class":271,"line":272},"line",1,[269,274,249],{"class":275},"sYn-s",[269,277,279],{"class":278},"sTbE_"," new",[269,281,282],{"class":278}," console",[269,284,286],{"class":285},"sz9Cv"," -n",[269,288,289],{"class":278}," MyApp",[269,291,293],{"class":292},"s9Tkl","   # create a console app in .\u002FMyApp\n",[269,295,297,301],{"class":271,"line":296},2,[269,298,300],{"class":299},"sJdAF","cd",[269,302,303],{"class":278}," MyApp\n",[269,305,307,309,312],{"class":271,"line":306},3,[269,308,249],{"class":275},[269,310,311],{"class":278}," run",[269,313,314],{"class":292},"                    # build + run\n",[269,316,318,320,323],{"class":271,"line":317},4,[269,319,249],{"class":275},[269,321,322],{"class":278}," build",[269,324,325],{"class":292},"                  # build only\n",[269,327,329,331,334,337,340],{"class":271,"line":328},5,[269,330,249],{"class":275},[269,332,333],{"class":278}," add",[269,335,336],{"class":278}," package",[269,338,339],{"class":278}," Newtonsoft.Json",[269,341,342],{"class":292},"   # add a NuGet package (like composer require)\n",[235,344,345,348],{},[247,346,347],{},"dotnet new console"," gives you two important files:",[350,351,352,366],"ul",{},[353,354,355,361,362,365],"li",{},[356,357,358],"strong",{},[247,359,360],{},"MyApp.csproj"," — the project manifest. Target framework, package\nreferences, settings. This is your ",[247,363,364],{},"composer.json",".",[353,367,368,373],{},[356,369,370],{},[247,371,372],{},"Program.cs"," — the entry point. Code here runs when the app starts.",[239,375,377],{"id":376},"a-typical-layout","A typical layout",[235,379,380,381,385,386,389],{},"Folders are for ",[382,383,384],"em",{},"organisation","; they don't create structure by themselves the way\nLaravel's autoloader maps directories. What actually connects files is the\n",[356,387,388],{},"namespace",", which by convention mirrors the folder path:",[260,391,396],{"className":392,"code":394,"language":395},[393],"language-text","MyApp\u002F\n├─ MyApp.csproj\n├─ Program.cs              \u002F\u002F entry point\n├─ Models\u002F\n│  └─ User.cs             \u002F\u002F namespace MyApp.Models\n├─ Services\u002F\n│  └─ LoginService.cs     \u002F\u002F namespace MyApp.Services\n└─ Helpers\u002F\n   └─ TextHelper.cs       \u002F\u002F namespace MyApp.Helpers\n","text",[247,397,394],{"__ignoreMap":265},[239,399,401,402,405],{"id":400},"namespaces-using-how-files-see-each-other","Namespaces & ",[247,403,404],{},"using"," — how files see each other",[235,407,408],{},"This is the one genuinely new concept vs PHP. Two steps:",[410,411,412,418],"ol",{},[353,413,414,415,417],{},"Each file declares a ",[356,416,388],{}," — a logical address for the types in it.",[353,419,420,421,425],{},"Another file pulls that namespace in with ",[356,422,423],{},[247,424,404],{}," to make those types visible.",[260,427,432],{"className":428,"code":429,"filename":430,"language":431,"meta":265,"style":265},"language-csharp shiki shiki-themes material-theme-lighter vitesse-light vitesse-dark","namespace MyApp.Services;   \u002F\u002F this file's address\n\npublic class LoginService { \u002F* ... *\u002F }\n","Services\u002FLoginService.cs","csharp",[247,433,434,454,460],{"__ignoreMap":265},[269,435,436,439,442,445,448,451],{"class":271,"line":272},[269,437,388],{"class":438},"s23sZ",[269,440,289],{"class":441},"sbc-P",[269,443,365],{"class":444},"soVBu",[269,446,447],{"class":441},"Services",[269,449,450],{"class":444},";",[269,452,453],{"class":292},"   \u002F\u002F this file's address\n",[269,455,456],{"class":271,"line":296},[269,457,459],{"emptyLinePlaceholder":458},true,"\n",[269,461,462,466,469,473,476,479],{"class":271,"line":306},[269,463,465],{"class":464},"s5Kfy","public",[269,467,468],{"class":438}," class",[269,470,472],{"class":471},"sD-vU"," LoginService",[269,474,475],{"class":444}," {",[269,477,478],{"class":292}," \u002F* ... *\u002F",[269,480,481],{"class":444}," }\n",[260,483,485],{"className":428,"code":484,"filename":372,"language":431,"meta":265,"style":265},"using MyApp.Services;       \u002F\u002F now LoginService is visible here\n\nvar service = new LoginService(\u002F* ... *\u002F);\n",[247,486,487,503,507],{"__ignoreMap":265},[269,488,489,492,494,496,498,500],{"class":271,"line":272},[269,490,404],{"class":491},"scgAs",[269,493,289],{"class":441},[269,495,365],{"class":444},[269,497,447],{"class":441},[269,499,450],{"class":444},[269,501,502],{"class":292},"       \u002F\u002F now LoginService is visible here\n",[269,504,505],{"class":271,"line":296},[269,506,459],{"emptyLinePlaceholder":458},[269,508,509,512,515,518,521,523,526,529],{"class":271,"line":306},[269,510,511],{"class":438},"var",[269,513,514],{"class":275}," service",[269,516,517],{"class":444}," =",[269,519,279],{"class":520},"sVsLi",[269,522,472],{"class":471},[269,524,525],{"class":444},"(",[269,527,528],{"class":292},"\u002F* ... *\u002F",[269,530,531],{"class":444},");\n",[533,534,535],"note",{},[235,536,537,538,541,542,545,546,553,554,556,557,560,561,564,565,568],{},"There's no ",[247,539,540],{},"require","\u002F",[247,543,544],{},"autoload"," step like PHP. The compiler sees ",[356,547,548,549,552],{},"every ",[247,550,551],{},".cs","\nfile in the project automatically"," — ",[247,555,404],{}," doesn't ",[382,558,559],{},"load"," the file, it just\nsaves you typing the full name (",[247,562,563],{},"MyApp.Services.LoginService","). Folder names and\nnamespaces don't ",[382,566,567],{},"have"," to match, but keeping them aligned is the convention and\nmakes files easy to find.",[239,570,572],{"id":571},"the-entry-point","The entry point",[235,574,575,576,579,580,582,583,586],{},"Modern C# (",[247,577,578],{},".NET 6+",") lets ",[247,581,372],{}," be plain top-level statements — no class\nor ",[247,584,585],{},"Main"," boilerplate needed:",[260,588,590],{"className":428,"code":589,"filename":372,"language":431,"meta":265,"style":265},"using MyApp.Models;\nusing MyApp.Services;\n\nvar users = new List\u003CUser>\n{\n    new User { Username = \"ada\", Password = \"secret\" }\n};\n\nvar loginService = new LoginService(users);\n\nConsole.Write(\"Username: \");\nvar username = Console.ReadLine() ?? \"\";\nConsole.Write(\"Password: \");\nvar password = Console.ReadLine() ?? \"\";\n\nvar user = loginService.Login(username, password);\nConsole.WriteLine(user is not null ? $\"Welcome, {user.Username}!\" : \"Invalid credentials.\");\n",[247,591,592,606,618,622,645,650,694,700,705,726,731,754,783,803,827,832,860],{"__ignoreMap":265},[269,593,594,596,598,600,603],{"class":271,"line":272},[269,595,404],{"class":491},[269,597,289],{"class":441},[269,599,365],{"class":444},[269,601,602],{"class":441},"Models",[269,604,605],{"class":444},";\n",[269,607,608,610,612,614,616],{"class":271,"line":296},[269,609,404],{"class":491},[269,611,289],{"class":441},[269,613,365],{"class":444},[269,615,447],{"class":441},[269,617,605],{"class":444},[269,619,620],{"class":271,"line":306},[269,621,459],{"emptyLinePlaceholder":458},[269,623,624,626,629,631,633,636,639,642],{"class":271,"line":317},[269,625,511],{"class":438},[269,627,628],{"class":275}," users",[269,630,517],{"class":444},[269,632,279],{"class":520},[269,634,635],{"class":471}," List",[269,637,638],{"class":444},"\u003C",[269,640,641],{"class":471},"User",[269,643,644],{"class":444},">\n",[269,646,647],{"class":271,"line":328},[269,648,649],{"class":444},"{\n",[269,651,653,656,659,661,665,667,671,674,677,680,683,685,687,690,692],{"class":271,"line":652},6,[269,654,655],{"class":520},"    new",[269,657,658],{"class":471}," User",[269,660,475],{"class":444},[269,662,664],{"class":663},"sSC40"," Username",[269,666,517],{"class":444},[269,668,670],{"class":669},"sbYkP"," \"",[269,672,673],{"class":278},"ada",[269,675,676],{"class":669},"\"",[269,678,679],{"class":444},",",[269,681,682],{"class":663}," Password",[269,684,517],{"class":444},[269,686,670],{"class":669},[269,688,689],{"class":278},"secret",[269,691,676],{"class":669},[269,693,481],{"class":444},[269,695,697],{"class":271,"line":696},7,[269,698,699],{"class":444},"};\n",[269,701,703],{"class":271,"line":702},8,[269,704,459],{"emptyLinePlaceholder":458},[269,706,708,710,713,715,717,719,721,724],{"class":271,"line":707},9,[269,709,511],{"class":438},[269,711,712],{"class":275}," loginService",[269,714,517],{"class":444},[269,716,279],{"class":520},[269,718,472],{"class":471},[269,720,525],{"class":444},[269,722,723],{"class":663},"users",[269,725,531],{"class":444},[269,727,729],{"class":271,"line":728},10,[269,730,459],{"emptyLinePlaceholder":458},[269,732,734,737,739,743,745,747,750,752],{"class":271,"line":733},11,[269,735,736],{"class":663},"Console",[269,738,365],{"class":444},[269,740,742],{"class":741},"sljsM","Write",[269,744,525],{"class":444},[269,746,676],{"class":669},[269,748,749],{"class":278},"Username: ",[269,751,676],{"class":669},[269,753,531],{"class":444},[269,755,757,759,762,764,767,769,772,775,778,781],{"class":271,"line":756},12,[269,758,511],{"class":438},[269,760,761],{"class":275}," username",[269,763,517],{"class":444},[269,765,766],{"class":663}," Console",[269,768,365],{"class":444},[269,770,771],{"class":741},"ReadLine",[269,773,774],{"class":444},"()",[269,776,777],{"class":520}," ??",[269,779,780],{"class":669}," \"\"",[269,782,605],{"class":444},[269,784,786,788,790,792,794,796,799,801],{"class":271,"line":785},13,[269,787,736],{"class":663},[269,789,365],{"class":444},[269,791,742],{"class":741},[269,793,525],{"class":444},[269,795,676],{"class":669},[269,797,798],{"class":278},"Password: ",[269,800,676],{"class":669},[269,802,531],{"class":444},[269,804,806,808,811,813,815,817,819,821,823,825],{"class":271,"line":805},14,[269,807,511],{"class":438},[269,809,810],{"class":275}," password",[269,812,517],{"class":444},[269,814,766],{"class":663},[269,816,365],{"class":444},[269,818,771],{"class":741},[269,820,774],{"class":444},[269,822,777],{"class":520},[269,824,780],{"class":669},[269,826,605],{"class":444},[269,828,830],{"class":271,"line":829},15,[269,831,459],{"emptyLinePlaceholder":458},[269,833,835,837,840,842,844,846,849,851,854,856,858],{"class":271,"line":834},16,[269,836,511],{"class":438},[269,838,839],{"class":275}," user",[269,841,517],{"class":444},[269,843,712],{"class":663},[269,845,365],{"class":444},[269,847,848],{"class":741},"Login",[269,850,525],{"class":444},[269,852,853],{"class":663},"username",[269,855,679],{"class":444},[269,857,810],{"class":663},[269,859,531],{"class":444},[269,861,863,865,867,870,872,875,878,881,884,887,890,893,896,899,901,904,907,910,912,915,917,920,922],{"class":271,"line":862},17,[269,864,736],{"class":663},[269,866,365],{"class":444},[269,868,869],{"class":741},"WriteLine",[269,871,525],{"class":444},[269,873,874],{"class":663},"user",[269,876,877],{"class":520}," is",[269,879,880],{"class":520}," not",[269,882,883],{"class":520}," null",[269,885,886],{"class":520}," ?",[269,888,889],{"class":669}," $\"",[269,891,892],{"class":278},"Welcome, ",[269,894,895],{"class":444},"{",[269,897,874],{"class":898},"su_V2",[269,900,365],{"class":444},[269,902,903],{"class":898},"Username",[269,905,906],{"class":444},"}",[269,908,909],{"class":278},"!",[269,911,676],{"class":669},[269,913,914],{"class":520}," :",[269,916,670],{"class":669},[269,918,919],{"class":278},"Invalid credentials.",[269,921,676],{"class":669},[269,923,531],{"class":444},[239,925,927],{"id":926},"laravel-net-tooling-cheat","Laravel → .NET tooling cheat",[929,930,931,944],"table",{},[932,933,934],"thead",{},[935,936,937,941],"tr",{},[938,939,940],"th",{},"Laravel \u002F PHP",[938,942,943],{},".NET",[945,946,947,958,970,983,996,1004],"tbody",{},[935,948,949,954],{},[950,951,952],"td",{},[247,953,364],{},[950,955,956],{},[247,957,360],{},[935,959,960,965],{},[950,961,962],{},[247,963,964],{},"composer require x",[950,966,967],{},[247,968,969],{},"dotnet add package x",[935,971,972,977],{},[950,973,974],{},[247,975,976],{},"composer install",[950,978,979,982],{},[247,980,981],{},"dotnet restore"," (runs automatically on build)",[935,984,985,991],{},[950,986,987,990],{},[247,988,989],{},"php artisan serve"," \u002F running the app",[950,992,993],{},[247,994,995],{},"dotnet run",[935,997,998,1001],{},[950,999,1000],{},"PSR-4 autoload (folder → namespace)",[950,1002,1003],{},"namespace convention (folder → namespace, but manual)",[935,1005,1006,1011],{},[950,1007,1008],{},[247,1009,1010],{},"vendor\u002F",[950,1012,1013,254,1016,1019],{},[247,1014,1015],{},"bin\u002F",[247,1017,1018],{},"obj\u002F"," (build output — gitignore these)",[239,1021,1023],{"id":1022},"where-to-go-next","Where to go next",[350,1025,1026,1033,1039],{},[353,1027,1028,1029],{},"Solidify the language → ",[1030,1031,1032],"a",{"href":64},"C# basics",[353,1034,1035,1036],{},"Model your data → ",[1030,1037,1038],{"href":68},"Classes & models",[353,1040,1041,1042],{},"Organise behaviour → ",[1030,1043,1044],{"href":72},"Services & helpers",[1046,1047,1048],"style",{},"html pre.shiki code .sYn-s, html code.shiki .sYn-s{--shiki-light:#E2931D;--shiki-default:#59873A;--shiki-dark:#80A665}html pre.shiki code .sTbE_, html code.shiki .sTbE_{--shiki-light:#91B859;--shiki-default:#B56959;--shiki-dark:#C98A7D}html pre.shiki code .sz9Cv, html code.shiki .sz9Cv{--shiki-light:#91B859;--shiki-default:#A65E2B;--shiki-dark:#C99076}html pre.shiki code .s9Tkl, html code.shiki .s9Tkl{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#A0ADA0;--shiki-default-font-style:inherit;--shiki-dark:#758575DD;--shiki-dark-font-style:inherit}html pre.shiki code .sJdAF, html code.shiki .sJdAF{--shiki-light:#6182B8;--shiki-default:#998418;--shiki-dark:#B8A965}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s23sZ, html code.shiki .s23sZ{--shiki-light:#E2931D;--shiki-default:#AB5959;--shiki-dark:#CB7676}html pre.shiki code .sbc-P, html code.shiki .sbc-P{--shiki-light:#90A4AE;--shiki-default:#2E8F82;--shiki-dark:#5DA994}html pre.shiki code .soVBu, html code.shiki .soVBu{--shiki-light:#39ADB5;--shiki-default:#999999;--shiki-dark:#666666}html pre.shiki code .s5Kfy, html code.shiki .s5Kfy{--shiki-light:#9C3EDA;--shiki-default:#AB5959;--shiki-dark:#CB7676}html pre.shiki code .sD-vU, html code.shiki .sD-vU{--shiki-light:#E2931D;--shiki-default:#2E8F82;--shiki-dark:#5DA994}html pre.shiki code .scgAs, html code.shiki .scgAs{--shiki-light:#F76D47;--shiki-default:#1E754F;--shiki-dark:#4D9375}html pre.shiki code .sVsLi, html code.shiki .sVsLi{--shiki-light:#39ADB5;--shiki-default:#AB5959;--shiki-dark:#CB7676}html pre.shiki code .sSC40, html code.shiki .sSC40{--shiki-light:#90A4AE;--shiki-default:#B07D48;--shiki-dark:#BD976A}html pre.shiki code .sbYkP, html code.shiki .sbYkP{--shiki-light:#39ADB5;--shiki-default:#B5695977;--shiki-dark:#C98A7D77}html pre.shiki code .sljsM, html code.shiki .sljsM{--shiki-light:#6182B8;--shiki-default:#59873A;--shiki-dark:#80A665}html pre.shiki code .su_V2, html code.shiki .su_V2{--shiki-light:#90A4AE;--shiki-default:#B56959;--shiki-dark:#C98A7D}",{"title":265,"searchDepth":306,"depth":306,"links":1050},[1051,1052,1053,1055,1056,1057],{"id":241,"depth":296,"text":242},{"id":376,"depth":296,"text":377},{"id":400,"depth":296,"text":1054},"Namespaces & using — how files see each other",{"id":571,"depth":296,"text":572},{"id":926,"depth":296,"text":927},{"id":1022,"depth":296,"text":1023},null,"2026-07-19","How C# files, namespaces, folders and the dotnet CLI fit together into a running app.",false,"md",[1064,1065,388,404,995,1066,1067,1068],"dotnet cli","csproj","dotnet new","solution","project layout",[],{},{"title":75,"description":1060},[431,249,1073,1074],"tooling","architecture","sJ4Op7xdwPJ-5Ge6Djty1eTam99MkL-GGLApYZekYEA",[1077,1079],{"title":71,"path":72,"stem":73,"description":1078,"children":-1},"Put code in another file — a service or a static helper — and call it from anywhere, the C# way.",{"title":79,"path":80,"stem":81,"description":1080,"children":-1},"Version control — everyday commands and getting out of trouble.",[1082,1092,1099,1102,1109,1115,1120,1125,1127,1129,1132,1140,1146,1149,1154,1157,1163,1166,1169,1174,1176,1179,1185,1189,1194,1197,1203,1207,1210,1215,1218,1221,1224,1227,1229,1235,1238,1243,1246,1250,1253,1260,1265,1268,1274],{"path":135,"title":134,"description":1083,"tags":1084,"category":120,"featured":1061,"updatedAt":1091,"createdAt":1091,"readingTime":756,"draft":1061},"Teams of four build one frontend application over the whole semester using AI, in a single shared GitHub repository where everyone contributes.",[1085,1086,1087,1088,1089,1090],"teaching","activity","capstone","github","ai","frontend","2026-08-01",{"path":169,"title":168,"description":1093,"tags":1094,"category":162,"featured":1061,"updatedAt":1091,"createdAt":1091,"readingTime":317,"draft":1061},"Create one repository, push your project, and add your teammates as collaborators so the whole team can work on the same code.",[1088,1095,1096,1097,1098],"git","collaboration","teamwork","setup",{"path":163,"title":162,"description":1100,"tags":1101,"category":162,"featured":1061,"updatedAt":1091,"createdAt":1091,"readingTime":272,"draft":1061},"Step-by-step references students can follow on their own during class.",[],{"path":159,"title":158,"description":1103,"tags":1104,"category":148,"featured":1061,"updatedAt":1108,"createdAt":1108,"readingTime":306,"draft":1061},"Install and configure the OpenCode CLI so AI writes code directly into your project folder instead of you copying it from a chat window.",[1089,1105,1106,1073,1107],"opencode","cli","workflow","2026-07-25",{"path":48,"title":47,"description":1110,"tags":1111,"category":37,"featured":1061,"updatedAt":1059,"createdAt":1059,"readingTime":296,"draft":1061},"A service should return a result and let the caller decide how to show it — the single most useful separation-of-concerns rule.",[1112,1074,1113,1114],"clean-code","separation-of-concerns","services",{"path":64,"title":63,"description":1116,"tags":1117,"category":1058,"featured":1061,"updatedAt":1059,"createdAt":1059,"readingTime":306,"draft":1061},"Types, variables, control flow and how to write a function (method) in C#, mapped from PHP.",[431,249,1118,1119],"basics","functions",{"path":68,"title":67,"description":1121,"tags":1122,"category":1058,"featured":1061,"updatedAt":1059,"createdAt":1059,"readingTime":306,"draft":1061},"Create a class, give it properties and a constructor, and use it — the C# version of a Laravel model.",[431,249,1123,1124],"classes","models",{"path":72,"title":71,"description":1078,"tags":1126,"category":1058,"featured":1061,"updatedAt":1059,"createdAt":1059,"readingTime":306,"draft":1061},[431,249,1114,1074],{"path":76,"title":75,"description":1060,"tags":1128,"category":1058,"featured":1061,"updatedAt":1059,"createdAt":1059,"readingTime":306,"draft":1061},[431,249,1073,1074],{"path":58,"title":57,"description":1130,"tags":1131,"category":1058,"featured":1061,"updatedAt":1059,"createdAt":1059,"readingTime":272,"draft":1061},"Learning C# and .NET from a Laravel\u002FPHP background — the fundamentals, mapped to what you already know.",[431,249,1118],{"path":20,"title":19,"description":1133,"tags":1134,"category":13,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"The core Eloquent relationship types with examples and the N+1 trap to avoid.",[1135,1136,1137,1138],"laravel","eloquent","database","orm","2026-07-17",{"path":24,"title":23,"description":1141,"tags":1142,"category":13,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"My quick reference for setting up and using Laravel Homestead during development.",[1135,1143,1144,1145],"homestead","vagrant","virtualbox",{"path":14,"title":13,"description":1147,"tags":1148,"category":13,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"The PHP framework for web artisans — Eloquent, routing, queues and more.",[],{"path":34,"title":33,"description":1150,"tags":1151,"category":27,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":296,"draft":1061},"Personal Bash aliases and helper functions that streamline my Laravel and Homestead development workflow.",[264,1152,1153,1143,1135],"bashrc","git bash",{"path":28,"title":27,"description":1155,"tags":1156,"category":27,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"Shell scripting and a faster life on the command line.",[],{"path":44,"title":43,"description":1158,"tags":1159,"category":37,"featured":458,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"Practical rules for naming variables, functions and types so code reads like prose.",[1112,1160,1161,1162],"naming","readability","craft",{"path":38,"title":37,"description":1164,"tags":1165,"category":37,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"Writing code that other people (and future you) can read.",[],{"path":52,"title":51,"description":1167,"tags":1168,"category":51,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"Getting reliable, useful results out of language models.",[],{"path":86,"title":85,"description":1170,"tags":1171,"category":79,"featured":458,"updatedAt":1139,"createdAt":1139,"readingTime":296,"draft":1061},"The Git commands I actually use day to day, plus how to undo things safely.",[1095,1106,1172,1173],"version-control","cheat-sheet",{"path":80,"title":79,"description":1080,"tags":1175,"category":79,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},[],{"path":6,"title":10,"description":1177,"tags":1178,"category":10,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"Languages, frameworks and the craft of building software.",[],{"path":109,"title":108,"description":1180,"tags":1181,"category":89,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":317,"draft":1061},"An introduction to AI-assisted software development, modern development workflows, and the mindset needed to use AI responsibly throughout the course.",[1089,1182,1183,1184],"software development","prompt engineering","beginners",{"path":113,"title":112,"description":1186,"tags":1187,"category":89,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":317,"draft":1061},"Learn how to write effective AI prompts and read JavaScript code confidently. This lesson teaches students how to direct AI instead of blindly copying its output.",[1089,1188,1183,1184],"javascript",{"path":117,"title":116,"description":1190,"tags":1191,"category":89,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":306,"draft":1061},"Introduction to the fundamentals of JavaScript, from variables and functions to loops, DOM manipulation, and events. This lesson prepares students for the Mini Product Store activity.",[1188,1184,1192,1193],"programming","web development",{"path":103,"title":102,"description":1195,"tags":1196,"category":102,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"Session-by-session plans with objectives, timing and materials.",[],{"path":127,"title":126,"description":1198,"tags":1199,"category":120,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":306,"draft":1061},"Build a personal portfolio website using JavaScript arrays, loops, and DOM manipulation instead of hardcoded HTML.",[1085,1086,1188,1200,1201,1202],"portfolio","dom","loops",{"path":131,"title":130,"description":1204,"tags":1205,"category":120,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":306,"draft":1061},"A JavaScript activity where students build a simple product store using arrays, loops, functions, DOM manipulation, and event listeners.",[1085,1086,1188,1201,1206,1202],"arrays",{"path":121,"title":120,"description":1208,"tags":1209,"category":120,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"In-class activities that get students doing, not just listening.",[],{"path":145,"title":144,"description":1211,"tags":1212,"category":120,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":296,"draft":1061},"Practice reading JavaScript code, predicting its output, and verifying your understanding before running the program.",[1085,1086,1188,1119,1213,1214],"if-statement","debugging",{"path":139,"title":138,"description":1216,"tags":1217,"category":138,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"Practice problems that build skill through repetition.",[],{"path":155,"title":154,"description":1219,"tags":1220,"category":148,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":317,"draft":1061},"A structured workflow for working with AI that emphasizes planning, review, and understanding before implementation.",[1089,1183,1107],{"path":149,"title":148,"description":1222,"tags":1223,"category":148,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"Prompt templates for teaching with and about AI.",[],{"path":97,"title":96,"description":1225,"tags":1226,"category":89,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"Lesson plans, activities, rubrics and student references.",[],{"path":90,"title":89,"description":1225,"tags":1228,"category":89,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},[],{"path":180,"title":179,"description":1230,"tags":1231,"category":172,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"Two tiny functions to control how often a handler runs — with the difference explained.",[1188,1232,1233,1234],"performance","snippets","events",{"path":173,"title":172,"description":1236,"tags":1237,"category":172,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"Small, copy-ready fragments you reach for again and again.",[],{"path":190,"title":189,"description":1239,"tags":1240,"category":162,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"The essential Vim motions and commands to get productive and get out.",[1241,1242,1173,1106],"vim","editor",{"path":183,"title":162,"description":1244,"tags":1245,"category":162,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"Dense, scannable references for commands and syntax.",[],{"path":201,"title":200,"description":1247,"tags":1248,"category":193,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"A reusable PR description template that makes reviews faster and kinder.",[1095,1088,1249,1096],"template",{"path":194,"title":193,"description":1251,"tags":1252,"category":193,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"Reusable starting points for files, configs and docs.",[],{"path":212,"title":211,"description":1254,"tags":1255,"category":204,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":296,"draft":1061},"The frontmatter and markdown conventions every note in this knowledge base follows.",[1256,1257,1258,1259],"meta","conventions","markdown","authoring",{"path":216,"title":215,"description":1261,"tags":1262,"category":204,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":296,"draft":1061},"Every formatting feature this knowledge base supports, on one page — a living reference and rendering test.",[1258,1263,1264],"mdc","reference",{"path":205,"title":204,"description":1266,"tags":1267,"category":204,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"How this knowledge base itself is built and maintained.",[],{"path":227,"title":226,"description":1269,"tags":1270,"category":219,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"What a CORS error actually means and how to fix it — on the server, where it belongs.",[1271,1272,1273,1214],"cors","http","apis",{"path":220,"title":219,"description":1275,"tags":1276,"category":219,"featured":1061,"updatedAt":1139,"createdAt":1139,"readingTime":272,"draft":1061},"Symptoms, causes and fixes for problems worth remembering.",[],1785598841281]