# Exercise: Dependency Injection

Write a cinema box office that is given its clock and price list, sells each seat once with a HashSet, keeps a waiting list in a Queue, and undoes sales with a Stack.

Journeyman · C# · OOP · Updated October 30, 2026

A small cinema needs a box office for its movie nights. Prices change with the time of day, a seat can only be sold once, a full house needs a waiting list, and the cashier needs an undo for the sale they didn't mean to make. You'll write the `BoxOffice` class.

## Get the exercise code

Open this lesson's GitHub repository, [github.com/ask-codey/exercise-dependency-injection](https://github.com/ask-codey/exercise-dependency-injection), also linked from the **Exercise** box beside the lesson. Click **Code**, then **Download ZIP**, and unzip it into your `bootcamp` folder. Or clone it with Git. Then open `MovieNight.slnx` in Visual Studio.

| File | What's in it |
|---|---|
| `MovieNight/Clock.cs` | Tells the time, ready to use |
| `MovieNight/PriceList.cs` | A matinee (before 5 PM) is $8.00, an evening ticket $12.00; ready to use |
| `MovieNight/BoxOffice.cs` | For you to finish. Its requirements are in the comment at the top. |
| `MovieNight.Tests` | Tests for `BoxOffice`, with a fake clock and a fake price list |

## What to do

1. **Fix the constructor.** It's given a `Clock` and a `PriceList`, but it ignores them and makes its own with `new`. Keep the ones it's given.
2. **`TicketPrice()`** asks the price list for the price at the clock's current time.
3. **Seats:** `Sell(seat)`, `IsSold(seat)` and `SoldCount`. A seat can only be sold once.
4. **The waiting list:** `JoinWaitingList(name)`, `WaitingCount`, and `ReleaseSeat(seat)`, which frees a seat and returns the first person waiting, or `null`.
5. **Undo:** `UndoLastSale()` cancels the most recent sale whose seat is still sold, and returns the seat, or `null`.

Run the program with **Ctrl+F5**, and the tests with **Test > Run All Tests**.

## Hints

- **One collection per job.** Sold seats can't repeat; the waiting list is first come, first served; undo works newest first. Which collection is each?
- **`HashSet.Add` and `Remove` return whether they changed anything.** That answers "was it already sold?" and "was it sold at all?" for you.
- **The fakes only work if you use what you're given.** The tests hand the box office a clock that's always 2 PM or 7 PM, and a price list where every ticket is $5.00.
- **`TryDequeue` and `TryPop`** return `false` when there's nothing left, instead of throwing.
- **Undo after a release:** a seat on the undo stack may have been released since. Keep popping until you find one that's still sold.

## When you're done

Every test passes. Notice that none of them depended on the time you ran them: that's the fake clock, and it only works because `BoxOffice` asks for its clock instead of making one.

## Submit your exercise

The exercise is how you finish this lesson. When your work is done, put it on GitHub in a repo of your own, then submit that repo's address here.

1. On GitHub, click **+**, then **New repository**. Name it (for example `exercise-dependency-injection`), choose **Public**, and click **Create repository**. Leave out the README: your folder already has one.
2. In a terminal in your exercise folder (Git Bash on Windows), send your work to your new repo. If you downloaded the ZIP:

   ```bash
   git init -b main
   git add .
   git commit -m "My solution"
   git remote add origin https://github.com/your-name/exercise-dependency-injection.git
   git push -u origin main
   ```

   If you cloned the starter instead, point your copy at your own repo, then commit and push:

   ```bash
   git remote set-url origin https://github.com/your-name/exercise-dependency-injection.git
   git add .
   git commit -m "My solution"
   git push -u origin main
   ```

3. Paste your repo's address, such as `https://github.com/your-name/exercise-dependency-injection`, into **Submit your exercise** on this page. The site checks that the repo is public and holds your commits, and then the lesson is complete.

Changed something after you submitted? Push it, and submit again: your latest submission is the one that counts.

## So what

Injected dependencies and the right collection for each job: a box office that's easy to test at any hour, where a seat can't be double-sold and nobody on the waiting list gets skipped.

## Key terms

- [Constructor Injection](https://www.ask-codey.com/glossary/constructor-injection-oop)
- [HashSet&lt;T>](https://www.ask-codey.com/glossary/hashset-t)
- [Queue&lt;T>](https://www.ask-codey.com/glossary/queue-t)
- [Stack&lt;T>](https://www.ask-codey.com/glossary/stack-t)

## Related

- [Constructor Injection](https://www.ask-codey.com/lessons/dependency-injection-constructor-injection)
- [HashSet](https://www.ask-codey.com/lessons/advanced-collections-in-csharp-hashset)
- [Queues](https://www.ask-codey.com/lessons/advanced-collections-in-csharp-queues)
- [Stacks](https://www.ask-codey.com/lessons/advanced-collections-in-csharp-stacks)

Source: https://www.ask-codey.com/lessons/exercise-dependency-injection
