Skip to content

Creating and Running Your First Project

Overview

Creating your first .NET project is an exciting milestone in your development journey. This guide walks you through creating various types of projects, understanding project structure, and running your applications successfully.

Prerequisites

Before starting, ensure you have:

# Verify .NET installation
dotnet --version

# Should show something like: 8.0.100
# If not installed, follow the installation guide

Your First Console Application

Step 1: Create the Project

# Create a new directory for your project
mkdir MyFirstProject
cd MyFirstProject

# Create console application
dotnet new console -n HelloWorld
cd HelloWorld

# Alternative: Create in current directory
dotnet new console

Step 2: Examine Project Structure

HelloWorld/
├── HelloWorld.csproj    # Project file
├── Program.cs           # Main program file
└── obj/                 # Build artifacts (auto-generated)

Step 3: Understanding the Project File

<!-- HelloWorld.csproj -->
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

Step 4: Examine the Program Code

// Program.cs (Traditional approach)
using System;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
        }
    }
}

// Program.cs (Modern top-level approach - .NET 6+)
Console.WriteLine("Hello, World!");

Step 5: Run Your Application

# Run the application
dotnet run

# Expected output:
# Hello, World!

Building a More Interactive Console App

Enhanced Program Example

// Program.cs - Interactive Console Application
using System;

Console.WriteLine("=== Welcome to My First .NET Application ===");
Console.WriteLine();

// Get user input
Console.Write("Please enter your name: ");
string? userName = Console.ReadLine();

Console.Write("Please enter your age: ");
string? ageInput = Console.ReadLine();

// Validate and process input
if (string.IsNullOrEmpty(userName))
{
    userName = "Anonymous";
}

if (int.TryParse(ageInput, out int age))
{
    Console.WriteLine();
    Console.WriteLine($"Hello, {userName}!");
    Console.WriteLine($"You are {age} years old.");

    if (age >= 18)
    {
        Console.WriteLine("You are an adult.");
    }
    else
    {
        Console.WriteLine($"You will be an adult in {18 - age} years.");
    }
}
else
{
    Console.WriteLine();
    Console.WriteLine($"Hello, {userName}!");
    Console.WriteLine("Invalid age entered, but nice to meet you!");
}

Console.WriteLine();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();

Running the Enhanced Application

# Build and run
dotnet build
dotnet run

# Or run directly
dotnet run

# Example interaction:
# === Welcome to My First .NET Application ===
# 
# Please enter your name: John Doe
# Please enter your age: 25
# 
# Hello, John Doe!
# You are 25 years old.
# You are an adult.
# 
# Press any key to exit...

Creating a Class Library

Step 1: Create the Library Project

# Create class library
dotnet new classlib -n MyLibrary
cd MyLibrary

Step 2: Create a Useful Class

// Calculator.cs
namespace MyLibrary
{
    public class Calculator
    {
        public int Add(int a, int b)
        {
            return a + b;
        }

        public int Subtract(int a, int b)
        {
            return a - b;
        }

        public int Multiply(int a, int b)
        {
            return a * b;
        }

        public double Divide(int a, int b)
        {
            if (b == 0)
                throw new ArgumentException("Cannot divide by zero", nameof(b));

            return (double)a / b;
        }

        public double GetCircleArea(double radius)
        {
            if (radius < 0)
                throw new ArgumentException("Radius cannot be negative", nameof(radius));

            return Math.PI * radius * radius;
        }
    }
}

Step 3: Create a Person Class

// Person.cs
namespace MyLibrary
{
    public class Person
    {
        public string FirstName { get; set; } = string.Empty;
        public string LastName { get; set; } = string.Empty;
        public DateTime BirthDate { get; set; }

        public string FullName => $"{FirstName} {LastName}";

        public int Age
        {
            get
            {
                var today = DateTime.Today;
                var age = today.Year - BirthDate.Year;

                if (BirthDate.Date > today.AddYears(-age))
                    age--;

                return age;
            }
        }

        public bool IsAdult => Age >= 18;

        public Person(string firstName, string lastName, DateTime birthDate)
        {
            FirstName = firstName;
            LastName = lastName;
            BirthDate = birthDate;
        }

        public override string ToString()
        {
            return $"{FullName} (Age: {Age})";
        }
    }
}

Creating a Console App That Uses the Library

Step 1: Create Solution Structure

# Go back to root directory
cd ..

# Create solution
dotnet new sln -n MyFirstSolution

# Add projects to solution
dotnet sln add HelloWorld/HelloWorld.csproj
dotnet sln add MyLibrary/MyLibrary.csproj

# Create new console app that uses the library
dotnet new console -n CalculatorApp
dotnet sln add CalculatorApp/CalculatorApp.csproj

# Add reference from console app to library
dotnet add CalculatorApp/CalculatorApp.csproj reference MyLibrary/MyLibrary.csproj

Step 2: Build the Calculator Console App

// CalculatorApp/Program.cs
using MyLibrary;

Console.WriteLine("=== Simple Calculator ===");
Console.WriteLine();

var calculator = new Calculator();
bool continueCalculation = true;

while (continueCalculation)
{
    try
    {
        Console.WriteLine("Choose an operation:");
        Console.WriteLine("1. Addition");
        Console.WriteLine("2. Subtraction");
        Console.WriteLine("3. Multiplication");
        Console.WriteLine("4. Division");
        Console.WriteLine("5. Circle Area");
        Console.WriteLine("6. Exit");
        Console.Write("Enter your choice (1-6): ");

        string? choice = Console.ReadLine();

        switch (choice)
        {
            case "1":
                PerformBasicOperation(calculator.Add, "Addition");
                break;
            case "2":
                PerformBasicOperation(calculator.Subtract, "Subtraction");
                break;
            case "3":
                PerformBasicOperation(calculator.Multiply, "Multiplication");
                break;
            case "4":
                PerformDivision(calculator);
                break;
            case "5":
                CalculateCircleArea(calculator);
                break;
            case "6":
                continueCalculation = false;
                Console.WriteLine("Thank you for using the calculator!");
                break;
            default:
                Console.WriteLine("Invalid choice. Please try again.");
                break;
        }

        if (continueCalculation)
        {
            Console.WriteLine();
            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
            Console.Clear();
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"An error occurred: {ex.Message}");
        Console.WriteLine();
    }
}

static void PerformBasicOperation(Func<int, int, int> operation, string operationName)
{
    Console.Write("Enter first number: ");
    if (int.TryParse(Console.ReadLine(), out int num1))
    {
        Console.Write("Enter second number: ");
        if (int.TryParse(Console.ReadLine(), out int num2))
        {
            int result = operation(num1, num2);
            Console.WriteLine($"{operationName} result: {result}");
        }
        else
        {
            Console.WriteLine("Invalid second number.");
        }
    }
    else
    {
        Console.WriteLine("Invalid first number.");
    }
}

static void PerformDivision(Calculator calculator)
{
    Console.Write("Enter first number: ");
    if (int.TryParse(Console.ReadLine(), out int num1))
    {
        Console.Write("Enter second number: ");
        if (int.TryParse(Console.ReadLine(), out int num2))
        {
            try
            {
                double result = calculator.Divide(num1, num2);
                Console.WriteLine($"Division result: {result:F2}");
            }
            catch (ArgumentException ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
            }
        }
        else
        {
            Console.WriteLine("Invalid second number.");
        }
    }
    else
    {
        Console.WriteLine("Invalid first number.");
    }
}

static void CalculateCircleArea(Calculator calculator)
{
    Console.Write("Enter radius: ");
    if (double.TryParse(Console.ReadLine(), out double radius))
    {
        try
        {
            double area = calculator.GetCircleArea(radius);
            Console.WriteLine($"Circle area: {area:F2}");
        }
        catch (ArgumentException ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
    else
    {
        Console.WriteLine("Invalid radius.");
    }
}

Step 3: Run the Calculator App

# Navigate to calculator app
cd CalculatorApp

# Run the application
dotnet run

# Or run from solution root
cd ..
dotnet run --project CalculatorApp

Creating Your First Web Application

Step 1: Create Web API Project

# Create web API project
dotnet new webapi -n MyFirstWebAPI
cd MyFirstWebAPI

# Add to solution
cd ..
dotnet sln add MyFirstWebAPI/MyFirstWebAPI.csproj

Step 2: Examine Web API Structure

MyFirstWebAPI/
├── Controllers/
│   └── WeatherForecastController.cs
├── Properties/
│   └── launchSettings.json
├── appsettings.json
├── appsettings.Development.json
├── MyFirstWebAPI.csproj
└── Program.cs

Step 3: Create a Simple API Controller

// Controllers/PersonController.cs
using Microsoft.AspNetCore.Mvc;
using MyLibrary;

namespace MyFirstWebAPI.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class PersonController : ControllerBase
    {
        [HttpGet]
        public ActionResult<IEnumerable<Person>> Get()
        {
            var people = new List<Person>
            {
                new Person("John", "Doe", new DateTime(1990, 5, 15)),
                new Person("Jane", "Smith", new DateTime(1985, 8, 22)),
                new Person("Bob", "Johnson", new DateTime(2000, 12, 3))
            };

            return Ok(people);
        }

        [HttpGet("{id}")]
        public ActionResult<Person> Get(int id)
        {
            if (id < 1 || id > 3)
                return NotFound();

            var people = new List<Person>
            {
                new Person("John", "Doe", new DateTime(1990, 5, 15)),
                new Person("Jane", "Smith", new DateTime(1985, 8, 22)),
                new Person("Bob", "Johnson", new DateTime(2000, 12, 3))
            };

            return Ok(people[id - 1]);
        }

        [HttpPost]
        public ActionResult<Person> Create([FromBody] CreatePersonRequest request)
        {
            if (string.IsNullOrEmpty(request.FirstName) || string.IsNullOrEmpty(request.LastName))
                return BadRequest("First name and last name are required.");

            var person = new Person(request.FirstName, request.LastName, request.BirthDate);
            return Ok(person);
        }
    }

    public class CreatePersonRequest
    {
        public string FirstName { get; set; } = string.Empty;
        public string LastName { get; set; } = string.Empty;
        public DateTime BirthDate { get; set; }
    }
}

Step 4: Add Library Reference to Web API

# Add reference to library
dotnet add MyFirstWebAPI/MyFirstWebAPI.csproj reference MyLibrary/MyLibrary.csproj

Step 5: Run the Web API

# Navigate to web API project
cd MyFirstWebAPI

# Run the application
dotnet run

# The application will start and show something like:
# info: Microsoft.Hosting.Lifetime[14]
#       Now listening on: https://localhost:7001
#       Now listening on: http://localhost:5000

Step 6: Test the API

# Test using curl (in another terminal)
curl https://localhost:7001/api/person

# Or test specific endpoints
curl https://localhost:7001/api/person/1

# Create new person
curl -X POST https://localhost:7001/api/person \
  -H "Content-Type: application/json" \
  -d '{"firstName":"Alice","lastName":"Wonder","birthDate":"1995-03-10T00:00:00"}'

Creating a Unit Test Project

Step 1: Create Test Project

# Create xUnit test project
dotnet new xunit -n MyLibrary.Tests

# Add to solution
dotnet sln add MyLibrary.Tests/MyLibrary.Tests.csproj

# Add reference to library being tested
dotnet add MyLibrary.Tests/MyLibrary.Tests.csproj reference MyLibrary/MyLibrary.csproj

Step 2: Write Unit Tests

// MyLibrary.Tests/CalculatorTests.cs
using Xunit;
using MyLibrary;

namespace MyLibrary.Tests
{
    public class CalculatorTests
    {
        private readonly Calculator _calculator;

        public CalculatorTests()
        {
            _calculator = new Calculator();
        }

        [Fact]
        public void Add_TwoPositiveNumbers_ReturnsSum()
        {
            // Arrange
            int a = 5;
            int b = 3;
            int expected = 8;

            // Act
            int result = _calculator.Add(a, b);

            // Assert
            Assert.Equal(expected, result);
        }

        [Fact]
        public void Subtract_TwoNumbers_ReturnsDifference()
        {
            // Arrange
            int a = 10;
            int b = 4;
            int expected = 6;

            // Act
            int result = _calculator.Subtract(a, b);

            // Assert
            Assert.Equal(expected, result);
        }

        [Fact]
        public void Multiply_TwoNumbers_ReturnsProduct()
        {
            // Arrange
            int a = 6;
            int b = 7;
            int expected = 42;

            // Act
            int result = _calculator.Multiply(a, b);

            // Assert
            Assert.Equal(expected, result);
        }

        [Fact]
        public void Divide_TwoNumbers_ReturnsQuotient()
        {
            // Arrange
            int a = 15;
            int b = 3;
            double expected = 5.0;

            // Act
            double result = _calculator.Divide(a, b);

            // Assert
            Assert.Equal(expected, result, 2); // 2 decimal places precision
        }

        [Fact]
        public void Divide_ByZero_ThrowsArgumentException()
        {
            // Arrange
            int a = 10;
            int b = 0;

            // Act & Assert
            Assert.Throws<ArgumentException>(() => _calculator.Divide(a, b));
        }

        [Theory]
        [InlineData(1, 3.14159)]
        [InlineData(2, 12.56636)]
        [InlineData(0, 0)]
        public void GetCircleArea_ValidRadius_ReturnsCorrectArea(double radius, double expectedArea)
        {
            // Act
            double result = _calculator.GetCircleArea(radius);

            // Assert
            Assert.Equal(expectedArea, result, 2);
        }

        [Fact]
        public void GetCircleArea_NegativeRadius_ThrowsArgumentException()
        {
            // Arrange
            double radius = -5;

            // Act & Assert
            Assert.Throws<ArgumentException>(() => _calculator.GetCircleArea(radius));
        }
    }
}

Step 3: Write Person Tests

// MyLibrary.Tests/PersonTests.cs
using Xunit;
using MyLibrary;

namespace MyLibrary.Tests
{
    public class PersonTests
    {
        [Fact]
        public void Constructor_ValidInput_CreatesPersonCorrectly()
        {
            // Arrange
            string firstName = "John";
            string lastName = "Doe";
            DateTime birthDate = new DateTime(1990, 5, 15);

            // Act
            var person = new Person(firstName, lastName, birthDate);

            // Assert
            Assert.Equal(firstName, person.FirstName);
            Assert.Equal(lastName, person.LastName);
            Assert.Equal(birthDate, person.BirthDate);
            Assert.Equal("John Doe", person.FullName);
        }

        [Fact]
        public void Age_BornInPast_ReturnsCorrectAge()
        {
            // Arrange
            var birthDate = DateTime.Today.AddYears(-25).AddDays(-100); // 25+ years ago
            var person = new Person("John", "Doe", birthDate);

            // Act
            int age = person.Age;

            // Assert
            Assert.True(age >= 25);
        }

        [Fact]
        public void IsAdult_PersonOver18_ReturnsTrue()
        {
            // Arrange
            var birthDate = DateTime.Today.AddYears(-20); // 20 years ago
            var person = new Person("John", "Doe", birthDate);

            // Act
            bool isAdult = person.IsAdult;

            // Assert
            Assert.True(isAdult);
        }

        [Fact]
        public void IsAdult_PersonUnder18_ReturnsFalse()
        {
            // Arrange
            var birthDate = DateTime.Today.AddYears(-16); // 16 years ago
            var person = new Person("Jane", "Doe", birthDate);

            // Act
            bool isAdult = person.IsAdult;

            // Assert
            Assert.False(isAdult);
        }

        [Fact]
        public void ToString_ReturnsFormattedString()
        {
            // Arrange
            var person = new Person("John", "Doe", new DateTime(1990, 5, 15));

            // Act
            string result = person.ToString();

            // Assert
            Assert.Contains("John Doe", result);
            Assert.Contains("Age:", result);
        }
    }
}

Step 4: Run Tests

# Run all tests
dotnet test

# Run tests with verbose output
dotnet test -v normal

# Run specific test project
dotnet test MyLibrary.Tests

# Run with coverage (requires additional packages)
dotnet test --collect:"XPlat Code Coverage"

Project Structure Best Practices

Final Solution Structure

MyFirstSolution/
├── MyFirstSolution.sln
├── src/
│   ├── MyLibrary/
│   │   ├── Calculator.cs
│   │   ├── Person.cs
│   │   └── MyLibrary.csproj
│   ├── HelloWorld/
│   │   ├── Program.cs
│   │   └── HelloWorld.csproj
│   ├── CalculatorApp/
│   │   ├── Program.cs
│   │   └── CalculatorApp.csproj
│   └── MyFirstWebAPI/
│       ├── Controllers/
│       ├── Program.cs
│       └── MyFirstWebAPI.csproj
└── tests/
    └── MyLibrary.Tests/
        ├── CalculatorTests.cs
        ├── PersonTests.cs
        └── MyLibrary.Tests.csproj

Organizing with Folders

# Create organized structure
mkdir src tests

# Move projects to appropriate folders
mv MyLibrary src/
mv HelloWorld src/
mv CalculatorApp src/
mv MyFirstWebAPI src/
mv MyLibrary.Tests tests/

# Update solution file references (automatic with newer .NET versions)
dotnet sln list  # Check current projects

Building and Running Everything

Build Entire Solution

# Build all projects in solution
dotnet build

# Build in Release mode
dotnet build -c Release

# Clean and rebuild
dotnet clean
dotnet build

Run Different Projects

# Run console app
dotnet run --project src/HelloWorld

# Run calculator app
dotnet run --project src/CalculatorApp

# Run web API
dotnet run --project src/MyFirstWebAPI

# Run tests
dotnet test tests/MyLibrary.Tests

Common Issues and Solutions

Issue 1: Project Reference Not Found

# Problem: Cannot find referenced project
# Solution: Check and fix project references
dotnet list reference
dotnet add reference ../MyLibrary/MyLibrary.csproj

Issue 2: Package Restore Issues

# Problem: NuGet packages not restored
# Solution: Restore packages
dotnet restore

# Clear cache if needed
dotnet nuget locals all --clear
dotnet restore

Issue 3: Build Errors

# Problem: Build fails
# Solution: Clean and rebuild
dotnet clean
dotnet build -v normal  # Verbose output for debugging

Next Steps

After creating your first projects:

  1. Learn NuGet package management
  2. Understand dependency injection
  3. Explore Entity Framework
  4. Build REST APIs

Summary

You've successfully created:

Project Type Purpose Key Learning
Console App Command-line application Basic .NET structure
Class Library Reusable code components Code organization
Web API REST API service Web development basics
Unit Tests Code quality assurance Testing fundamentals

These foundational projects demonstrate core .NET concepts and provide a solid base for more advanced development. Practice building variations of these project types to strengthen your understanding of .NET development patterns.