Tutorials / Build a REST API with C# and .NET · Lesson 3 of 15

On this page

    .NET Project Types

    This is a reference page, not a step-by-step lesson. Come back to it whenever you start something new and wonder, "which template do I pick?"

    Every project starts with a command like dotnet new console or dotnet new webapi. The word after new is the template, and it decides what kind of project you get.

    Here is the whole page in one table:

    Template Runs by itself? One-line picture Bookshop example
    classlib No A toolbox with no power switch Database code used by several projects
    console Yes, then stops A chore you do once A one-off script that fixes old data
    worker Yes, keeps running An electric fan A job that sends order emails all day
    webapi Yes, waits for requests A clerk who answers questions The API behind the shop's website
    mvc / razor Yes, waits for requests A waiter who brings a finished meal A staff back-office website
    mstest / xunit / nunit Only when testing A quality inspector Checks that the price maths is right

    Class library (classlib)

    Think of a toolbox with no power switch. It is useful code sitting in one place, but you cannot start it or run it. It only becomes useful when another, runnable project borrows something from it.

    A class library can be shared at two levels.

    Level 1: inside your own solution. This is the common case. Several projects in the same solution need the same code, so you write it once and each of them adds a plain ProjectReference to it.

    Level 1: sharing inside one solution One solution (the common case) each project adds a ProjectReference to Data Api OrderWorker Data (library)

    There is nothing to publish and no version numbers. Change Data, rebuild, and everyone sees the change straight away.

    Level 2: outside your solution. Another team or another company cannot add a ProjectReference, because they are not in your solution. So you publish the library as a NuGet package. NuGet is the shared shelf where .NET packages live, and consumers install from it the same way they install any popular package.

    Level 2: sharing outside your solution Your library publish NuGet package Other teams or solutions They install it with: dotnet add package

    💡 Do not jump to Level 2 "just in case". Build the library for the projects that need it today, inside your own solution. Publish it as a NuGet package only when a second solution or team really needs it. Publishing early adds version-management work for a need that does not exist yet.

    Where you will see it:

    • Database code shared by an API and a background job, so both follow the same rules instead of two slightly different copies.
    • Business rules ("what counts as a valid order") shared by an API and an admin tool, so they always agree.
    • Small helpers used everywhere, such as encrypting text or creating PDF files.

    Console app (console)

    Think of a chore you do once, then you are done. You run it, it does its job from start to finish, and then it closes itself. Nothing keeps running afterwards.

    Where you will see it:

    • A script that runs one time to move old data into a new format.
    • A small tool someone runs by hand, or on a timer, to clean up old log files or send a report.
    • A throwaway project to try out one idea in isolation before building it properly.

    Worker service (worker)

    This is the one people mix up with the console app, so let's go slowly.

    A console app is like a microwave. You set it, it runs, and when the job is done it beeps and stops by itself.

    A worker service is like an electric fan. Switch it on and it keeps spinning, with no built-in "I'm finished" moment, until someone switches it off.

    That is the whole difference: a console app runs once and stops. A worker service keeps running and repeats its task on a loop.

    Why a special template? Writing your own "keep running forever" loop is easy to get wrong. What happens when the computer restarts? How do you stop it cleanly without cutting a task off halfway? The worker template already handles these for you. A plain console app gives you none of it.

    Where you will see it:

    • A job that keeps checking whether new orders have arrived and sends a confirmation email for each one.
    • A job that wakes up every few minutes to look for new data somewhere else.
    • A job that watches a folder and processes each new file the moment it appears.
    • A job that listens for messages from another system and reacts to each one.

    ASP.NET Core Web API (webapi)

    Think of a clerk who only answers questions and never speaks first. It sits quietly, and when something (a web page, an app, another program) asks, it hands back an answer. The answer is usually data in a format called JSON, not a finished web page. An API is built to be talked to by other code, not read by a person.

    This is the project type we build in this tutorial.

    Where you will see it:

    • The back end behind a website built with a front-end framework such as Vue or React. The website asks the API for data and shows it.
    • The back end behind a phone app. One API can serve both an iPhone app and an Android app.
    • One internal system asking another for information, with no person involved.
    • A company opening up some of its data so outside developers can build on it.

    ASP.NET Core MVC and Razor Pages

    Think of a waiter who brings you a fully cooked meal, where the web API was a clerk handing you ingredients. When someone visits a page, the server builds the whole finished page (text, layout, everything) and sends it to the browser. The browser has nothing left to assemble.

    • MVC groups related pages under one controller. For example, an OrdersController might handle "show all orders", "show one order", "create an order" and "edit an order", because they belong together.
    • Razor Pages does the same job more simply: one page, one file, with no bigger controller around it. It suits a page that mostly stands on its own.

    Where you will see it:

    • An internal dashboard or back-office tool used by a company's own staff. Many older systems are built this way.
    • A public website where it matters that search engines such as Google can easily read each page.
    • A single simple page, like a settings page, where a whole controller would be more setup than the page needs. That is a good fit for Razor Pages.
    • A multi-step process, like checkout, where grouping step 1, 2 and 3 under one controller makes sense.

    Test project (MSTest, xUnit or NUnit)

    This one is different: it never stands alone. It always sits next to another project, and its only job is to check that the other project's code works. It borrows the real project's code to test it, but nothing borrows from the test project.

    Think of a quality inspector at a factory. The inspector does not build the product. They poke at the finished item to make sure it works before it ships. No product, no inspector.

    Where you will see it:

    • Checking one small piece of business logic on its own, with no real database or network.
    • Checking that several pieces work correctly together, closer to real life.
    • A safety net that runs automatically on every proposed code change, before it can be merged.
    • A small test that proves a bug exists. You fix the bug and keep the test forever, so if the bug ever comes back, the test catches it straight away.

    Desktop apps: WPF and WinForms

    These build traditional Windows programs: the kind you install and open in their own window, with buttons and forms, instead of visiting in a browser. They are still used for internal tools and older software that was never meant to be a website.

    Think of an appliance you own outright, like a microwave on your counter. It is installed once, lives on your machine, and needs no browser or web address. A website is more like a restaurant you have to visit, because the kitchen is somewhere else.

    They are outside what this tutorial covers, but it helps to know the names in case you ever end up maintaining one.


    Questions to think about

    Before the next lesson, try answering these in your own words. There are no answers given here on purpose. If you can explain them out loud to a friend, you are ready to move on.

    1. Which template would you pick for each job, and why? (a) A tool you run once to fix old book prices. (b) A job that keeps checking for new orders all day. (c) The back end behind a bookshop phone app.
    2. What is the difference between a console app and a worker service? Why is there a special worker template?
    3. A class library cannot run by itself. How can two projects in the same solution share one? When would you publish it as a NuGet package instead?
    4. A web API and an MVC site both answer requests. What is different about what each one sends back? Which one would you use for a staff page that the server builds whole?
    5. Why can a test project never stand alone? What does it need from another project?
    ← Solution and Project PlanningDependency Injection Basics →