- Lab
-
Libraries: If you want this lab, consider one of these libraries.
- Core Tech
Shape Text and Employee Behavior in C#
Contoso Staffing's HR reps type new-hire details directly into a console tool during onboarding: names, department codes, and badge numbers arrive with inconsistent spacing and casing. The toolkit you build cleans that raw text, slices badge codes into their department-prefix and employee-number parts, masks sensitive digits when displaying them, and turns the cleaned data into Employee objects that track hire behavior like check-ins and tenure. By the end, HR reps can type messy input and get back a consistent, safely encapsulated employee directory entry.
Lab Info
Table of Contents
-
Challenge
Step 1: Orientation - Meet the employee onboarding toolkit
Step 1: Orientation - Meet the employee onboarding toolkit
Contoso Staffing's HR reps type new-hire details straight into a console tool while they're on the phone with a hiring manager: names arrive as
jamie riveraorJAMIE RIVERA, department codes asengorENG, and badge numbers as a single unbroken string likeENG4821. None of that text is safe to store or display as-is. Over the next four steps you'll build a small toolkit that cleans it up, slices it apart, and turns it into a properly modeledEmployeeobject. ## Where you'll workAll of your edits happen under
src/:src/InputNormalizer.cs- trims and case-normalizes raw console text, and compares normalized values for equality.src/BadgeProcessor.cs- slices badge codes likeENG4821into a department prefix and an employee number, and builds a masked version for display.src/Employee.cs- models a hired employee with fields for name, department, badge code, and hire date, plus behavior for tenure and check-ins.src/OnboardingService.cs- wires the normalizer, the badge processor, and theEmployeeclass together into one onboarding flow.
Each file already compiles; the methods you'll complete are marked with
// TODOcomments. Runbash runTest.sh Task_2_1, with any task's number, at any point to check that task on its own. ## How the steps build on each other- Step 2 puts you in
InputNormalizer.cs, working with raw strings straight from the console: declaring and reading them, then trimming and case-normalizing soengandENGare recognized as the same value. - Step 3 moves to
BadgeProcessor.cs, where you'll use zero-basedSubstringcalls to pull a badge code apart and build a masked replacement without ever changing the original string - strings in C# can't be mutated in place. - Step 4 introduces
Employee.cs: a class with fields that hold an employee's state, and instance methods that compute tenure and record check-ins from that state. - Step 5 locks those fields behind private access, adds a validated way to change them, and finally assembles all three files into a working onboarding pipeline in
OnboardingService.cs.
By the end, a single call chain will take messy console text all the way to a safely encapsulated
Employeerecord. You can start with the raw text.If you get stuck, you can refer to the provided solution code for each task, available in the
solutionfolder.info> This lab experience was developed by the Pluralsight team using an internally developed AI tool. All sections were verified by human experts for accuracy prior to publications. However, content may still contain errors or inaccuracies, and we recommend independent verification.
To report a problem or provide feedback, click here. Feedback may be used to improve accuracy in accordance with our Privacy Policy. -
Challenge
Step 2: Capture and normalize employee text input
Capturing raw text before you can trust it
Every onboarding record starts as plain text an HR rep types at the console - a name, a department code, sometimes both padded with stray spaces or typed in whatever case felt natural at the time. Before you can compare or store that text, you need a place to declare it, read it in, and echo it back so the rep can confirm what was captured. That's the job of
src/InputNormalizer.cs, starting withBuildEmployeeHeader. ## Trimming and case, togetherA header that faithfully echoes raw input still isn't safe to compare -
' eng'and'ENG 'are the same department to a human but different strings to==. The fix is normalization: trim the whitespace, then force a single consistent case, so every representation of the same value collapses to one string.NormalizeEmployeeTextis where that happens, and every later comparison in this toolkit builds on it. ## Comparing normalized valuesWith normalization in place, equality checks become straightforward - normalize both sides, then compare.
IsMatchingDepartmentputs that pattern to work directly, and it's the same pattern you'll reuse in Step 5 when a badge's department prefix has to be checked against an employee's stored department. -
Challenge
Step 3: Slice and reshape badge codes without losing the original
Slicing a badge code by position
A badge code like
ENG4821packs two pieces of information into one string: a three-letter department prefix and a four-digit employee number, with no separator between them. C#'sSubstringextracts a piece by position -Substring(start, length)orSubstring(start)- using zero-based indexing, so the very first character sits at index 0.src/BadgeProcessor.csstarts by pulling the prefix off the front. ## Extracting what's leftOnce the prefix is isolated, the employee number is everything after it. The single-argument
Substring(start)overload takes everything from that index to the end of the string, which is exactly the shape you need when the trailing portion can vary - not every badge number needs to be the same length. ## Reshaping text without touching the originalStrings in C# are immutable: no method call ever changes the characters inside an existing string, it only ever hands you back a new one. That guarantee is exactly what makes masking safe -
MaskEmployeeNumberbuilds a brand-new string with most digits hidden behind*, while thebadgeCodeparameter it was given keeps its original value for anything else that still needs it. -
Challenge
Step 4: Model employees with fields and instance methods
From strings to a modeled employee
Cleaned, sliced text is still just text.
src/Employee.csturns it into something the rest of the system can reason about: a class with fields forName,Department,BadgeCode,HireDate, and aCheckInCount, plus instance methods that read and update that state. The constructor is the first piece - it's what turns four loose values into one coherent object. ## Computing behavior from stored stateOnce an
Employeeholds its ownHireDate, tenure isn't something you pass around separately - it's something the object can compute for itself on demand, from a date you supply.ComputeTenureYearsusesDateTimesubtraction to get aTimeSpan, then converts that elapsed time into whole years. ## Methods that change state, not just read itNot every instance method only reports on existing fields - some update them.
CheckInis that kind of method: each call should leave the object's state different from before, incrementing a running count and reflecting that new count in the message it returns. -
Challenge
Step 5: Encapsulate behavior and assemble the onboarding tool
Locking fields behind a public API
So far,
Employee's fields have been open to direct assignment from anywhere - convenient while you were building the class, but risky once other code depends on it: nothing stops a caller from settingDepartmentto blank or garbage text. Encapsulation fixes that by making fields private and exposing change only through methods that validate first.UpdateDepartmentis that validated entry point for one field. ## Assembling the pipelineWith normalization, badge slicing, and a properly encapsulated
Employeeclass all in place,src/OnboardingService.csis where they finally meet.ProcessNewHiretakes the four raw values an HR rep types in, runs them throughInputNormalizerandBadgeProcessor, and returns one clean confirmation - the same shape of work you did by hand in Steps 2 and 3, now happening in a single call. ## Validating across objects before actingThe last piece ties badge data back to the employee it belongs to: a check-in should only succeed if the badge's department prefix actually matches the employee's stored department.
RegisterCheckIncombinesBadgeProcessor.ExtractDepartmentPrefixandInputNormalizer.IsMatchingDepartmentto guard the call toemployee.CheckIn(), so a mismatched badge is reported, not recorded. -
Challenge
Step 6: Run the application
Every task is done, and each one was graded the moment you completed it. What you have not done yet is watch the whole application run at once -- which is the only place the pieces you wrote separately become a single working program.
Start the application
Open the Terminal tab and run:
dotnet run --project src/Lab.csprojThe program runs in the terminal and prints its output there. Every behaviour it shows is code you wrote in the previous steps, so read the output against what each task asked for -- that is the whole lab, working as one program. ### Run the checks yourself
The lab ran each task's test for you as you went, but they are ordinary tests and you can rerun any of them whenever you like, one task at a time:
bash runTest.sh Task_2_1Swap in the number of the task you want to check. Each failure names the task it belongs to, so the output tells you which step to go back to rather than which line to stare at. Two things worth trying before you finish: break something on purpose and watch the matching check fail, then put it back. Knowing what a failure looks like is worth as much as knowing what a pass looks like, and it costs you nothing here.
When you are done, everything you wrote is still in the editor tabs -- the lab is yours to keep reading.
About the author
Real skill practice before real-world application
Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.
Learn by doing
Engage hands-on with the tools and technologies you’re learning. You pick the skill, we provide the credentials and environment.
Follow your guide
All labs have detailed instructions and objectives, guiding you through the learning process and ensuring you understand every step.
Turn time into mastery
On average, you retain 75% more of your learning if you take time to practice. Hands-on labs set you up for success to make those skills stick.