Skip to content

CSharp Workshop

Rainer Stropek edited this page Feb 14, 2021 · 1 revision

C# Workshop

Introduction

I regularly use this project for teaching C#. In this document, I summarize how you can build it with classes step by step.

Setup Solution

GitHub

API

  • Create ASP.NET Core Web API (.NET 5) project called NBattleshipCodingContest
    • Remove auto-generated demo code

Logic Library

Logic Library Tests

  • Create xUnit Test Project (.NET 5) called NBattleshipCodingContest.Logic.Tests
    • Remove auto-generated demo code
    • Change project settings according to NBattleshipCodingContest.Players.Tests
    • Reference logic library from logic test project
    • Add Moq NuGet package for mocking
  • Discuss:
    • Code quality in unit test projects

Add Fundamental Data Structures

Logic Library

  • Copy the following files from the sample project:
    • Assembly.cs
    • ModelEnums.cs
    • BoardIndex.cs
    • BoardIndexJsonConverter.cs
    • BoardIndexRange.cs
  • Discuss C# constructs in copied files, in particular in:
    • BoardIndex.cs
    • BoardIndexJsonConverter.cs
    • BoardIndexRange.cs

Logic Library Tests

  • Copy the following files from the sample project:
    • BoardIndexConverterTests.cs
    • BoardIndexTests.cs
    • BoardIndexRangeTests.cs
  • Discuss:
    • Structure of unit tests
    • InternalsVisibleTo (Assembly.cs)
  • Run tests to make sure everything is ok

Build and Test Automation

  • Add LiquidTestReports.Markdown NuGet packages to test project
  • Copy .github/workflows/build.yaml from the sample project
  • Add, commit, push to GitHub
  • Discuss:
    • Build and test automation with GitHub actions

Board Content

Logic Library

  • Copy the following files from the sample project:
    • BoardContent.cs
    • BoardContentJsonConverter.cs
    • IReadOnlyBoard.cs
    • ReadOnlyBoardExtensions.cs
  • Discuss C# constructs in copied files

Logic Library Tests

  • Copy the following files from the sample project:
    • BoardContentTest.cs
    • BoardContentConverterTests.cs
    • ReadOnlyBoardExtensionsTests.cs
  • Discuss theories and facts
  • Run tests to make sure everything is ok

GitHub

  • Add, commit, push to GitHub
  • Verify that tests succeeded in GitHub Actions

Battleship Board

Logic Library

  • Copy the following files from the sample project:
    • BattleshipBoard.cs
    • BoardTooOccupiedException.cs
    • RandomBoardFiller.cs
  • Discuss:
    • Class/interface structure (BoardRelatedTypes.cs)
    • C# constructs in copied files

Logic Library Tests

  • Copy the following files from the sample project:
    • BattleshipBoardTests.cs
    • RandomBoardFillerTests.cs
    • ShipPlacementCheckerTests.cs
  • Discuss mocking in RandomBoardFillerTests.cs
  • Run tests to make sure everything is ok

GitHub

  • Add, commit, push to GitHub
  • Verify that tests succeeded in GitHub Actions

Game

Logic Library

  • Copy the following files from the sample project:
    • Game.cs
    • Model.cs
  • Discuss use of C# records

Logic Library Tests

  • Copy the following files from the sample project:
    • GameTests.cs
  • Discuss use of C# records
  • Run tests to make sure everything is ok

GitHub

  • Add, commit, push to GitHub
  • Verify that tests succeeded in GitHub Actions

C# Source Generators

Project Setup

  • Add Class Library (.NET Standard 2.0) project called NBattleshipCodingContest.PlayersGenerator
  • Create xUnit Test Project (.NET 5) called NBattleshipCodingContest.PlayersGenerator.Tests
    • Remove auto-generated demo code
    • Change project settings according to NBattleshipCodingContest.PlayersGenerator.Tests
    • Add Moq NuGet package for mocking
    • Add LiquidTestReports.Markdown NuGet packages
    • Add Microsoft.CodeAnalysis.CSharp and Microsoft.CodeAnalysis.Analyzers for C# Source Generators
    • Reference players generator library from test project
  • Add Class Library (.NET 5) project called NBattleshipCodingContest.Players
    • Remove auto-generated demo code
    • Change project settings according to NBattleshipCodingContest.Players.csproj
    • Reference logic library
    • Reference players generator like a code analyzer (OutputItemType="Analyzer" ReferenceOutputAssembly="false")
  • Create xUnit Test Project (.NET 5) called NBattleshipCodingContest.Players.Tests
  • Check NuGet packages, consolidate any inconsistencies

Base Types in Players Library

  • Copy the following files from the sample project:
    • IgnoreAttribute.cs
    • PlayerBase.cs
    • PlayerInfo.cs
  • Copy some sample players from sample project:
    • RandomShots.cs
    • Sequential.cs
    • SmartRandomShots.cs
  • Discuss how to write a player

Player Tests

  • Copy the following files from the sample project:
    • SequentialTests.cs
  • Run tests to make sure everything is ok

Source Generator Library

  • Copy the following files from the sample project:
    • Assembly.cs
    • PlayersGenerator.cs
  • Discuss structure of source generator, code walkthrough

Source Generator Tests

  • Copy the following files from the sample project:
    • PlayersGeneratorTest.cs
  • Run tests to make sure everything is ok

Demo Source Generator

  • Add temporary demo project GeneratedPlayers (.NET 5 Console App)

    • Reference players library
  • Replace code in Program.cs with:

    using System;
    using NBattleshipCodingContest.Players;
    foreach(var p in PlayerList.Players)
    {
        Console.WriteLine(p.Name);
    }
  • Remove demo project

GitHub

  • Add, commit, push to GitHub
  • Verify that tests succeeded in GitHub Actions

gRPC Manager/Battle Host Communication

Note: gRPC is not a core topic in this workshop. Therefore, we are going to copy the entire project into our solution and briefly discuss how gRPC works.

  • Copy NBattleshipCodingContest.Protocol project
  • Copy NBattleshipCodingContest.Protocol.Tests project
  • Discuss gRPC aspects of the code
  • Run tests to make sure everything is ok
  • Add, commit, push to GitHub
  • Verify that tests succeeded in GitHub Actions

Main Application

Basics

  • Settings
    • Change project settings and dependencies according to NBattleshipCodingContest.csproj
    • Reference logic library, players library, and protocol library from web API
  • Copy the following files from the sample project:
    • AboutOptions.cs
    • appsettings.json
    • PlayerListOptions.cs
    • Program.cs
    • All .cs files from ConsoleGame
  • Remove all references from Program.cs to files we have not copied so far
  • Try:
    • dotnet run -- help
    • dotnet run -- version
    • dotnet run -- players
    • dotnet run -- consolegame -p 0 -q 2
  • Discuss:
    • Command-line options with CommandLineParser
    • Logging with Serilog

Manager and Battlehost

  • Copy the following files from the sample project:
    • All .cs files from Manager
    • All .cs files from BattleHost
    • All .cs files from Controllers
    • Program.cs (overwrite it)
    • All files from wwwroot
  • Configure embedded resources of project according to NBattleshipCodingContest.csproj
  • Discuss:
    • Starting of gRPC server
    • UI as embedded resource
  • Try: