Skip to main content
ANVISoftware Solutions

Employee Management Console Application

Intermediate15-25 hours

The C# course project. Build it with what you know early, then deliberately refactor it as the language gives you better tools.

The brief

What the finished thing needs to do.

  • Add, view, update and remove employees
  • Each employee has a name, role, department, salary and joining date
  • List employees, filter by department, and sort by salary or name
  • Report headcount and average salary per department
  • Validate input: no negative salaries, no empty names, no future joining dates
  • Save to a file and load on startup

How to structure it

This project is built three times, and that is the point. The first version uses classes and loops. The second introduces interfaces and separates storage from logic. The third replaces manual loops with LINQ and makes the file access asynchronous.

Keep the earlier versions. Comparing them is the most instructive part of the exercise — you will see abstraction earning its place rather than being asserted as good practice.

Target structure by the final version: an Employee model, an IEmployeeStore interface with a file-based implementation, a service holding the business rules, and a thin console layer that only handles input and output.

Why these technologies

Console application
No web or UI concerns, so the language and structure stay in focus.
Interface for storage
Lets the business rules be tested without touching the filesystem.
JSON file persistence
Readable, requires no database, and keeps the focus on C# rather than SQL.
LINQ in the final version
The reporting requirements are exactly what LINQ expresses well — introduced after you have written the loops by hand.

Build it in this order

Each stage produces something that works. That matters — a project that only runs at the very end is a project people abandon.

  1. Model and in-memory list

    An Employee class and a List. Add and display only.

  2. Full CRUD

    Update and remove, matching on a stable id rather than a name.

  3. Validation

    Reject invalid input at the point of entry, with specific messages.

  4. Filtering and sorting

    Write these with loops first. Keep this version.

  5. Reporting with loops

    Headcount and average salary per department, using dictionaries and loops.

  6. Extract a storage interface

    Move persistence behind IEmployeeStore. The service should not know about files.

  7. Add file persistence

    Implement the interface with JSON serialisation.

  8. Refactor to LINQ

    Replace the filtering, sorting and reporting loops. Compare against the earlier version.

  9. Make I/O asynchronous

    Convert file access to async and let it flow through the call chain.

  10. Add tests

    Test the service against an in-memory store implementation. This is only possible because of the interface.

Done means

How to know it is finished

Check each of these before moving on. If one fails, the project is not done yet — and that is useful information rather than a setback.

  • All operations work and data survives a restart
  • Invalid input is rejected with a message naming the problem
  • Reports produce correct figures, verified against data you can check by hand
  • Business logic is testable without touching the filesystem
  • The final version uses LINQ and async where they genuinely improve the code

If you want to go further

Extensions worth attempting

Only once the core build meets every criterion above.

  • Replace file storage with a database via EF Core, changing only the store implementation
  • Add a salary history per employee and report changes over time
  • Export a report to CSV
  • Add a simple permission model for who may change salaries

Have a project worth talking through?

Tell us what you're building or what's slowing your current system down. We'll give you a direct read on scope and approach.