L18 — Final Project Defense
Each student presents and defends their final C# + .NET MAUI + PostgreSQL project one-on-one with the instructor. Rubric-based grading and verification questions.
Assignment Reference
Students defend the final course project: a cross-platform .NET MAUI desktop/mobile application that uses MVVM and connects to a PostgreSQL database for full CRUD.
Scope (minimum):
- At least two domain tables in PostgreSQL, with one foreign-key relationship between them
- A main screen that lists records and a detail/form screen for create + edit
- Working Create, Read, Update, Delete for at least one of the two tables
- Input validation on the form (non-empty, number ranges, date ranges as appropriate)
- MVVM: all data logic in ViewModels, no SQL in code-behind
- A
Repositoryclass (or equivalent) wrapping Npgsql — the ViewModel must not reference Npgsql types - Runs on at least Windows Machine; Android target is a bonus
Domain examples (student picks one, or proposes their own):
- Library (books + authors)
- School (students + courses)
- Fitness tracker (workouts + exercises)
- Personal finance (accounts + transactions)
- Recipe box (recipes + ingredients)
Grading Rubric
| # | Criterion | Max points | Notes |
|---|---|---|---|
| 1 | Project builds and runs on Windows without errors | 10 | Clean build, no missing NuGet packages, no crash on launch |
| 2 | Database schema — two tables, foreign key, sensible types | 10 | Inspected via \d in psql or pgAdmin. Nulls, types, PK/FK correct. |
| 3 | Read — list screen shows data from the database | 10 | Rows come from PostgreSQL, not hard-coded. |
| 4 | Create — form adds a new row; it appears in the list and in the DB | 15 | Verified by re-reading the list and querying the table. |
| 5 | Update — editing an existing row persists | 10 | Change survives app restart. |
| 6 | Delete — removing a row persists | 10 | Change survives app restart. |
| 7 | Input validation — invalid input is rejected gracefully | 10 | Empty name, out-of-range numbers, bad date → clear error message, no crash. |
| 8 | MVVM discipline — no SQL/Npgsql in code-behind; ViewModel has no UI types | 10 | Code inspection of at least one ViewModel + one page code-behind. |
| 9 | Parameterised queries — no string concatenation into SQL | 5 | Code inspection of the repository. |
| 10 | Code quality — naming, file layout, using on connections, no dead code | 5 | General impression on walk-through. |
| 11 | Oral defense — answers verification questions correctly | 5 | See question list below. |
| Total | 100 |
Grade bands:
- 90–100 → A
- 75–89 → B
- 60–74 → C
- < 60 → retake
Verification Questions
The instructor will pick 3–4 questions from this list during the defense. A confident answer earns full points for criterion 11; a partial answer earns partial points.
- Architecture. Walk me through what happens when the user taps "Add" — from button press to row in PostgreSQL.
- MVVM. Why is the SQL in a repository class and not in the ViewModel or the page's code-behind? What would break if we moved it?
- Data binding. Point at a
{Binding SomeProperty}in your XAML. What object does it actually bind to, and how does the page know? - Change notification. If a property in your ViewModel changes but the UI doesn't update, what's almost certainly missing? Show me where you implemented it.
- Connections. Show me where you open an
NpgsqlConnection. How is it closed? What would happen if it weren't? - Parameters. Show me a query that takes user input. Why did you use a
@parameterinstead of string concatenation? Demonstrate how the safe version blocks SQL injection. - Foreign keys. Which of your two tables has the foreign key? What happens in your app if the referenced row is deleted?
- Validation. I'm the user. I type
-500into the age field and press Add. Walk me through what happens in your code. - Error handling. I shut down PostgreSQL while your app is running, then press "Refresh". What does your app do? What should it do?
- Reload vs. in-memory update. After adding a row, do you re-fetch from the database or just append to the
ObservableCollection? What are the trade-offs? - Async. Are your database calls synchronous or asynchronous? If synchronous — what would a user feel on a slow connection? If asynchronous — show me an
await. - Navigation. How does the user move between your two screens? Walk me through the Shell route registration.
Note to instructor: pick questions that target the parts of the student's actual code. If they built a library app, ask about the authors→books FK (Q7). If their update is in-memory only, ask Q10. Don't use a generic set — use the student's own project as the context.
Submission Checklist
Before your defense slot starts, make sure the following are ready:
- Project compiles cleanly with no warnings about missing packages
- PostgreSQL is running and accepts your connection string
- Your
students/ domain tables contain at least 3 seed rows so the list has something to show - The app runs on Windows Machine (ideally in release configuration — faster startup)
- You can open the project in Visual Studio and navigate to any file the instructor asks for in under 10 seconds
- You can open
psql(or pgAdmin) and runSELECT * FROM your_tablealongside the app to show rows updating - You have a connection string that works on the classroom machine (if different from home, update it before class)
- Optional but recommended: a one-page README with the domain description, the schema, and a screenshot
On the day of the defense:
- Arrive 5 minutes before your slot
- Have the project already open and the database already started
- Bring your laptop fully charged — the defense bench has 1 outlet
- Close Discord, Telegram, and anything else before sharing your screen
- Be ready to demo Add → Update → Delete in under 2 minutes; the instructor will ask for it
Good luck! The hard work is behind you — this is your chance to show it off.