Learning Path Details
Foundation in C#: Common Project Types from Tim Corey
Description:
Module 7 of the Complete Foundation in C# Course Series, we cover the most common project types in .NET, including Class Libraries, Unit Tests, WinForms, WPF Core, ASP.NET Core Razor Pages, ASP.NET Core MVC, and ASP.NET Core API.
Key Takeaways:
We are introduced to each of the most common project types in .NET. To make comparisons easier, each of the projects after Unit Tests uses the same Class Library and builds the same application, using the different technologies. Each project type also gets its own mini-project challenge, where we build it ourselves first, before seeing how Tim would do it.
Technologies Learned:
- .NET;
- .NET Core;
- .NET Core 3.0;
- .NET Framework;
- .NET Framework 4.8;
- .NET Standard;
- .NET Standard 2.0;
- ASP.NET Core Web API;
- ASP.NET Core Web App (Model-View-Controller);
- ASP.NET Core Web App (Razor Pages);
- C#;
- Class Library;
- Console Application;
- Unit Tests;
- Windows Forms Application;
- WPF Application;
- XAML;
- xUnit Test Project;
This learning resource was completed on 9/18/2021.
Find the Resource here:
Practice Projects
ASP.NET Core API Mini Project
Description:
The homework from the Lesson 15, Mini Project - ASP.NET Core API, of Module 7, Common Project Types, of the Complete Foundation in C# Course Series from Tim Corey. We are to build a WebAPI Core application with two POST commands. Create a POST that takes in a person's info and another that takes in address info.
Technologies Used:
- .NET;
- .NET Core;
- .NET Core 3.1;
- ASP.NET Core Web API;
- C#;
- Class Library;
Find the Project here:
https://github.com/Spartan-CSharp/ProjectTypes-ASP.NETCoreAPIMiniProject
Code Snippet:
using System.Collections.Generic;
using ClassLibrary;
using Microsoft.AspNetCore.Mvc;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace APIWebApplicationUI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class PersonController : ControllerBase
{
private readonly PersonModel _person;
public PersonController(PersonModel person)
{
_person = person;
}
// GET: api/Person
[HttpGet]
public IEnumerable<PersonModel> Get()
{
List<PersonModel> people = new List<PersonModel>();
if ( !string.IsNullOrWhiteSpace(_person.FirstName) && !string.IsNullOrWhiteSpace(_person.LastName) )
{
people.Add(_person);
}
return people;
}
// GET api/Person/5
[HttpGet("{id}")]
public PersonModel Get(int id)
{
return _person;
}
// POST api/Person
[HttpPost]
public void Post([FromBody] PersonModel value)
{
_person.FirstName = value.FirstName;
_person.LastName = value.LastName;
_person.IsActive = value.IsActive;
_person.Addresses = value.Addresses;
}
// PUT api/Person/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] PersonModel value)
{
_person.FirstName = value.FirstName;
_person.LastName = value.LastName;
_person.IsActive = value.IsActive;
_person.Addresses = value.Addresses;
}
// DELETE api/<PersonController>/5
[HttpDelete("{id}")]
public void Delete(int id)
{
_person.FirstName = "";
_person.LastName = "";
_person.IsActive = false;
_person.Addresses.Clear();
}
}
}
ASP.NET Core API
Description:
The homework from the Lesson 14, ASP.NET Core API Project Type, of Module 7, Common Project Types, of the Complete Foundation in C# Course Series from Tim Corey. We are to build a Web API Application that has a GET call that takes in a First Name and Last Name and it returns "Hi {FN} {LN}".
Technologies Used:
- .NET;
- .NET Core;
- .NET Core 3.1;
- ASP.NET Core Web API;
- C#;
Find the Project here:
https://github.com/Spartan-CSharp/ProjectTypes-ASP.NETCoreAPI
Code Snippet:
using Microsoft.AspNetCore.Mvc;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace SayHi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class PersonController : ControllerBase
{
// GET: api/Person
[HttpGet]
public string Get(string firstName, string lastName)
{
return $"Hi {firstName} {lastName}!";
}
}
}
ASP.NET Core MVC Mini Project
Description:
The homework from the Lesson 13, Mini Project - ASP.NET Core MVC, of Module 7, Common Project Types, of the Complete Foundation in C# Course Series from Tim Corey. We are to build a Core MVC application with two pages. Create a page that takes in a person's info and another that takes in address info (no need to associate it).
Technologies Used:
- .NET;
- .NET Core;
- .NET Core 3.1;
- ASP.NET Core Web Application (Model-View-Controller);
- C#;
- Class Library;
Find the Project here:
https://github.com/Spartan-CSharp/ProjectTypes-ASP.NETCoreMVCMiniProject
Code Snippet:
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using MVCWebApplicationUI.Models;
namespace MVCWebApplicationUI.Controllers
{
public class PersonController : Controller
{
private readonly ILogger<PersonController> _logger;
[BindProperty]
private PersonViewModel _person { get; set; }
public PersonController(ILogger<PersonController> logger, PersonViewModel person)
{
_logger = logger;
_person = person;
}
// GET: Person
public ActionResult Index()
{
List<PersonViewModel> people = new List<PersonViewModel>();
if ( !string.IsNullOrWhiteSpace(_person.FirstName) && !string.IsNullOrWhiteSpace(_person.LastName) )
{
people.Add(_person);
}
_logger.LogInformation("GET, Person Controller, Index View, Person View Model");
return View(people);
}
// GET: Person/Details/5
public ActionResult Details(int id)
{
_logger.LogInformation("GET, Person Controller, Details View, Person View Model with Id = {id}", id);
return View(_person);
}
// GET: Person/Create
public ActionResult Create()
{
_logger.LogInformation("GET, Person Controller, Details View, Person View Model");
_person.FirstName = "";
_person.LastName = "";
_person.IsActive = false;
_person.Addresses.Clear();
return View(_person);
}
// POST: Person/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(PersonViewModel person)
{
_logger.LogInformation("POST, Person Controller, Details View, Person View Model with FirstName = {FirstName}, LastName = {LastName}, IsActive = {IsActive}, and {AddressCount} Addresses", person.FirstName, person.LastName, person.IsActive, person.Addresses.Count);
try
{
if ( ModelState.IsValid )
{
_person.FirstName = person.FirstName;
_person.LastName = person.LastName;
_person.IsActive = person.IsActive;
_person.Addresses.Clear();
foreach ( AddressViewModel address in person.Addresses )
{
_person.Addresses.Add(address);
}
return RedirectToAction(nameof(Details), new { id = 5 });
}
else
{
return View(person);
}
}
catch
{
return View(person);
}
}
// GET: Person/Edit/5
public ActionResult Edit(int id)
{
_logger.LogInformation("GET, Person Controller, Edit View, Person View Model with Id = {id}", id);
return View(_person);
}
// POST: Person/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int id, PersonViewModel person)
{
_logger.LogInformation("POST, Person Controller, Edit View, Person View Model with Id = {id}, FirstName = {FirstName}, LastName = {LastName}, IsActive = {IsActive}, and {AddressCount} Addresses", id, person.FirstName, person.LastName, person.IsActive, person.Addresses.Count);
try
{
if ( ModelState.IsValid )
{
_person.FirstName = person.FirstName;
_person.LastName = person.LastName;
_person.IsActive = person.IsActive;
_person.Addresses.Clear();
foreach ( AddressViewModel address in person.Addresses )
{
_person.Addresses.Add(address);
}
return RedirectToAction(nameof(Details), new { id = 5 });
}
else
{
return View(person);
}
}
catch
{
return View(person);
}
}
// GET: Person/Delete/5
public ActionResult Delete(int id)
{
_logger.LogInformation("GET, Person Controller, Delete View, Person View Model with Id = {id}", id);
return View(_person);
}
// POST: Person/Delete/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Delete(int id, PersonViewModel person)
{
_logger.LogInformation("POST, Person Controller, Edit View, Person View Model with Id = {id}, FirstName = {FirstName}, LastName = {LastName}, IsActive = {IsActive}, and {AddressCount} Addresses", id, person.FirstName, person.LastName, person.IsActive, person.Addresses.Count);
try
{
_person.FirstName = "";
_person.LastName = "";
_person.IsActive = false;
_person.Addresses.Clear();
return RedirectToAction(nameof(Index));
}
catch
{
return View(person);
}
}
}
}
ASP.NET Core MVC
Description:
The homework from the Lesson 12, ASP.NET Core MVC Project Type, of Module 7, Common Project Types, of the Complete Foundation in C# Course Series from Tim Corey. We are to build a Core MVC Application that has a simple data-entry page with First and Last Name fields. Have a button say "Hi {FN} {LN}" when pressed.
Technologies Used:
- .NET;
- .NET Core;
- .NET Core 3.1;
- ASP.NET Core Web Application (Model-View-Controller);
- C#;
Find the Project here:
https://github.com/Spartan-CSharp/ProjectTypes-ASP.NETCoreMVC
Code Snippet:
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using SayHi.Models;
namespace SayHi.Controllers
{
public class SayHiController : Controller
{
private readonly ILogger<SayHiController> _logger;
[BindProperty]
private PersonModel Person { get; set; } = new PersonModel();
public SayHiController(ILogger<SayHiController> logger)
{
_logger = logger;
}
// GET: SayHi
public ActionResult Index()
{
_logger.LogInformation("GET, SayHi Controller, Index View, Person Model");
return View();
}
// GET: SayHi/Create
public ActionResult Create()
{
_logger.LogInformation("GET, Say Hi Controller, Create View, Person Model");
return View();
}
// GET: SayHi/Details
public ActionResult Details(PersonModel person)
{
_logger.LogInformation("GET, Say Hi Controller, Details View, PersonModel Model: {person}", person);
Person = person;
return View(Person);
}
// POST: SayHi/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(PersonModel person)
{
_logger.LogInformation("POST, Say Hi Controller, Create View, Person Model: {person}", person);
try
{
if ( ModelState.IsValid )
{
Person.FirstName = person.FirstName;
Person.LastName = person.LastName;
return RedirectToAction(nameof(Details), Person);
}
else
{
return RedirectToAction(nameof(Index));
}
}
catch
{
return View();
}
}
}
}
ASP.NET Core Razor Pages Mini Project
Description:
The homework from the Lesson 11, Mini Project - ASP.NET Core Razor Pages, of Module 7, Common Project Types, of the Complete Foundation in C# Course Series from Tim Corey. We are to build a Razor Pages application with two pages. Create a page that takes in a person's info and another that takes in address info (no need to associate it).
Technologies Used:
- .NET Core;
- .NET Core 3.1;
- ASP.NET Core Web Application (Razor Pages);
- C#;
- Class Library;
Find the Project here:
https://github.com/Spartan-CSharp/ProjectTypes-ASP.NETCoreRazorPagesMiniProject
Code Snippet:
using System.Collections.Generic;
using ClassLibrary;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
namespace RazorPagesWebApplicationUI.Pages
{
public class PersonEntryModel : PageModel
{
private readonly ILogger<PersonEntryModel> _logger;
private readonly PersonModel _person;
[BindProperty]
public string FirstName
{
get; set;
}
[BindProperty]
public string LastName
{
get; set;
}
[BindProperty]
public bool IsActive
{
get; set;
}
[BindProperty]
public List<AddressModel> Addresses
{
get; set;
} = new List<AddressModel>();
public PersonEntryModel(ILogger<PersonEntryModel> logger, PersonModel person)
{
_logger = logger;
_person = person;
}
public void OnGet()
{
FirstName = _person.FirstName;
LastName = _person.LastName;
IsActive = _person.IsActive != null && (bool)_person.IsActive;
Addresses = _person.Addresses;
_logger.LogInformation("On GET Person Entry Page, Person Entry Model");
}
public IActionResult OnPost()
{
_person.FirstName = FirstName;
_person.LastName = LastName;
_person.IsActive = IsActive;
_logger.LogInformation("On POST Person Entry Page, Person Entry Model, with First Name {FirstName}, Last Name {LastName}, Is Active {IsActive}, and {AddressCount} Addresses", _person.FirstName, _person.LastName, _person.IsActive, _person.Addresses.Count);
return RedirectToPage("./Index");
}
public IActionResult OnPostAdd()
{
_person.FirstName = FirstName;
_person.LastName = LastName;
_person.IsActive = IsActive;
_logger.LogInformation("On POST Person Entry Page to Add Address, Person Entry Model, with First Name {FirstName}, Last Name {LastName}, Is Active {IsActive}, and {AddressCount} Addresses", _person.FirstName, _person.LastName, _person.IsActive, _person.Addresses.Count);
return RedirectToPage("./AddressEntry");
}
}
}
ASP.NET Core Razor Pages
Description:
The homework from the Lesson 10, ASP.NET Core Razor Pages Project Type, of Module 7, Common Project Types, of the Complete Foundation in C# Course Series from Tim Corey. We are to build a Razor Pages Application that has a simple data-entry page with First and Last Name fields. Have a button say "Hi {FN} {LN}" when pressed.
Technologies Used:
- .NET;
- .NET Core;
- .NET Core 3.1;
- ASP.NET Core Web Application (Razor Pages);
- C#;
Find the Project here:
https://github.com/Spartan-CSharp/ProjectTypes-ASP.NETCoreRazorPages
Code Snippet:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
namespace SayHi.Pages
{
public class IndexModel : PageModel
{
[BindProperty]
public string FirstName
{
get; set;
}
[BindProperty]
public string LastName
{
get; set;
}
[BindProperty]
public string Greeting
{
get; set;
}
private readonly ILogger<IndexModel> _logger;
public IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}
public void OnGet()
{
_logger.LogInformation("On GET Index Page, Index Model");
}
public IActionResult OnPost()
{
Greeting = $"Hi {FirstName} {LastName}!";
_logger.LogInformation("On POST Index Page, Index Model, with Greeting = {Greeting}", Greeting);
return Page();
}
}
}
WPF Core Mini Project
Description:
The homework from the Lesson 9, Mini Project - WPF Core, of Module 7, Common Project Types, of the Complete Foundation in C# Course Series from Tim Corey. We are to build a WPF application with two forms. Create a form that takes in a person's info and another that takes in address info (multiple per person).
Technologies Used:
- .NET;
- .NET Core;
- .NET Core 3.1;
- C#;
- Class Library;
- WPF Application;
- XAML;
Find the Project here:
https://github.com/Spartan-CSharp/ProjectTypes-WPFCoreMiniProject
Code Snippet:
<Window x:Name="personEntryWindow" x:Class="WPFCoreUI.PersonEntryWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WPFCoreUI" mc:Ignorable="d" FontSize="24" Title="Person Entry Window" Height="600" Width="450" MinWidth="250" MinHeight="350">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
<RowDefinition Height="auto" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="1" Grid.Column="1" Margin="0 5 5 5">First Name</TextBlock>
<TextBox x:Name="firstNameTextBox" Grid.Row="1" Grid.Column="2" MinWidth="150" Margin="5 5 0 5" Padding="5" />
<TextBlock Grid.Row="2" Grid.Column="1" Margin="0 5 5 5">Last Name</TextBlock>
<TextBox x:Name="lastNameTextBox" Grid.Row="2" Grid.Column="2" MinWidth="150" Margin="5 5 0 5" Padding="5" />
<TextBlock Grid.Row="3" Grid.Column="1" Margin="0 5 5 5">Active</TextBlock>
<CheckBox x:Name="activeChecBox" Grid.Row="3" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="5 5 0 5" Padding="5" />
<TextBlock Grid.Row="4" Grid.Column="1" Margin="0 5 5 5">Addresses</TextBlock>
<Button x:Name="addAddressButton" Grid.Row="4" Grid.Column="2" Margin="5 5 0 5" Padding="5" Width="75" Height="40" HorizontalAlignment="Right" Click="AddAddressButton_Click">Add</Button>
<ListBox x:Name="addressesListBox" Grid.Row="5" Grid.Column="1" Grid.ColumnSpan="2" Margin="0 0 0 5" Padding="5">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Margin="0 2 2 2" Padding="1" Text="{Binding StreetAddress}" />
<TextBlock Margin="2 2 2 2" Padding="1" Text="{Binding City}" />
<TextBlock Margin="2 2 2 2" Padding="1" Text="{Binding State}" />
<TextBlock Margin="2 2 0 2" Padding="1" Text="{Binding ZipCode}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button x:Name="saveRecordButton" Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="2" Margin="5" Padding="5" Width="200" Height="50" Click="SaveRecordButton_Click">Save</Button>
</Grid>
</Window>
WPF Core
Description:
The homework from the Lesson 8, WPF Core Project Type, of Module 7, Common Project Types, of the Complete Foundation in C# Course Series from Tim Corey. We are to build a WPF Application that has a simple data-entry screen with First and Last Name fields. Have a button say "Hi {FN} {LN}" when pressed.
Technologies Used:
- .NET;
- .NET Core;
- .NET Core 3.1;
- C#;
- WPF Application;
- XAML;
Find the Project here:
Code Snippet:
<Window x:Class="SayHi.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SayHi"
mc:Ignorable="d" Title="Say Hi!" Height="450" Width="800" FontSize="24">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="*" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="2" Grid.Column="2">
<TextBlock Margin="5">First Name:</TextBlock>
<TextBox x:Name="firstNameTextBox" MinWidth="100" MaxWidth="200" Padding="5"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="2" Grid.Column="3">
<TextBlock Margin="5">Last Name:</TextBlock>
<TextBox x:Name="lastNameTextBox" MinWidth="100" MaxWidth="200" Padding="5"></TextBox>
</StackPanel>
<Button x:Name="sayHiButton" Grid.Row="3" Grid.Column="2" Grid.ColumnSpan="2" Click="SayHiButton_Click" Margin="10">Say Hi!</Button>
<TextBlock x:Name="sayHiTextBlock" Grid.Row="4" Grid.Column="2" Grid.ColumnSpan="2" Text="{Binding}" Margin="10" />
</Grid>
</Window>
WinForms Mini Project
Description:
The homework from the Lesson 7, Mini Project - WinForms of Module 7, Common Project Types, of the Complete Foundation in C# Course Series from Tim Corey. We are to build a WinForms application with two forms. Create a form that takes in a person's info and another that takes in address info (multiple per person).
Technologies Used:
- .NET;
- .NET Framework;
- .NET Framework 4.8;
- C#;
- Class Library;
- Windows Forms Application;
Find the Project here:
https://github.com/Spartan-CSharp/ProjectTypes-WinFormsMiniProject
Code Snippet:
using System;
using System.ComponentModel;
using System.Windows.Forms;
using ClassLibrary;
namespace WindowsFormsUI
{
public partial class PersonEntry : Form, ISaveAddress
{
private string _firstName = "";
private string _lastName = "";
private readonly BindingList<AddressModel> _addressList = new BindingList<AddressModel>();
private readonly PersonModel _person = new PersonModel();
public PersonEntry()
{
InitializeComponent();
WireUpLists();
}
private void WireUpLists()
{
firstNameTextBox.Text = _firstName;
lastNameTextBox.Text = _lastName;
addressesListBox.DataSource = _addressList;
addressesListBox.DisplayMember = nameof(AddressModel.FormattedAddress);
}
private void AddAddressButton_Click(object sender, EventArgs e)
{
AddressEntry addressentry = new AddressEntry(this, _person.FullName);
addressentry.Show();
}
public void SaveAddress(AddressModel address)
{
_addressList.Add(address);
_person.Addresses.Add(address);
}
private void FirstNameTextBox_TextChanged(object sender, EventArgs e)
{
_firstName = firstNameTextBox.Text;
_person.FirstName = _firstName;
}
private void LastNameTextBox_TextChanged(object sender, EventArgs e)
{
_lastName = lastNameTextBox.Text;
_person.LastName = _lastName;
}
}
}
WinForms
Description:
The homework from the Lesson 6, WinForm Project Type, of Module 7, Common Project Types, of the Complete Foundation in C# Course Series from Tim Corey. We are to build a WinForms Application that has a simple data-entry screen with First and Last Name fields. Have a button say "Hi {FN} {LN}" when pressed.
Technologies Used:
- .NET;
- .NET Framework;
- .NET Framework 4.8;
- C#;
- Windows Forms Application;
Find the Project here:
Code Snippet:
using System;
using System.Windows.Forms;
namespace SayHi
{
public partial class SayHi : Form
{
public SayHi()
{
InitializeComponent();
}
private void SayHiButton_Click(object sender, EventArgs e)
{
if ( string.IsNullOrWhiteSpace(firstNameTextBox.Text) && string.IsNullOrWhiteSpace(lastNameTextBox.Text) )
{
_ = MessageBox.Show("You must enter both a First Name and a Last Name to Say Hi!", "First Name and Last Name Blank", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
_ = firstNameTextBox.Focus();
}
else if ( string.IsNullOrWhiteSpace(firstNameTextBox.Text) )
{
_ = MessageBox.Show("You must enter both a First Name to Say Hi!", "First Name Blank", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
_ = firstNameTextBox.Focus();
}
else if ( string.IsNullOrWhiteSpace(lastNameTextBox.Text) )
{
_ = MessageBox.Show("You must enter a Last Name to Say Hi!", "Last Name Blank", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
_ = lastNameTextBox.Focus();
}
else
{
_ = MessageBox.Show($"Hi {firstNameTextBox.Text} {lastNameTextBox.Text}!", "Hi there!", MessageBoxButtons.OK, MessageBoxIcon.None);
firstNameTextBox.Text = "";
lastNameTextBox.Text = "";
_ = firstNameTextBox.Focus();
}
}
}
}
Unit Test Mini Project
Description:
The homework from the Lesson 5, Mini Project - Unit Tests, of Module 7, Common Project Types, of the Complete Foundation in C# Course Series from Tim Corey. We are to build a Class Library (.NET Standard) with a class that does the basic math operations. Create unit tests for all methods.
Technologies Used:
- .NET;
- .NET Core;
- .NET Core 3.1;
- .NET Standard;
- .NET Standard 2.1;
- C#;
- Class Library;
- xUnit Test Project;
Find the Project here:
https://github.com/Spartan-CSharp/ProjectTypes-UnitTestMiniProject
Code Snippet:
using Xunit;
namespace CalculationLibrary.Tests
{
public class CalculationsTests
{
[Fact]
public void BasicAddTest()
{
// Arrange
int expected = 7;
// Act
int actual = Calculations.Add(3, 4);
// Assert
Assert.Equal(expected, actual);
}
[Fact]
public void BasicSubtractTest()
{
// Arrange
int expected = -1;
// Act
int actual = Calculations.Subtract(3, 4);
// Assert
Assert.Equal(expected, actual);
}
[Fact]
public void BasicMultiplyTest()
{
// Arrange
int expected = 12;
// Act
int actual = Calculations.Multiply(3, 4);
// Assert
Assert.Equal(expected, actual);
}
[Fact]
public void BasicDivideTest()
{
// Arrange
int expected = 0;
// Act
int actual = Calculations.Divide(3, 4);
// Assert
Assert.Equal(expected, actual);
}
[Theory]
// Arrange
[InlineData(-3, -4, -7)]
[InlineData(-3, 4, 1)]
[InlineData(3, -4, -1)]
[InlineData(3, 4, 7)]
[InlineData(4, -4, 0)]
[InlineData(4, 4, 8)]
[InlineData(0, -4, -4)]
[InlineData(0, 4, 4)]
[InlineData(0, 0, 0)]
[InlineData(-3, 0, -3)]
[InlineData(3, 0, 3)]
[InlineData(-4, -3, -7)]
[InlineData(4, -3, 1)]
[InlineData(-4, 3, -1)]
[InlineData(4, 3, 7)]
[InlineData(-4, 4, 0)]
[InlineData(-4, 0, -4)]
[InlineData(4, 0, 4)]
[InlineData(0, -3, -3)]
[InlineData(0, 3, 3)]
[InlineData(-8, -4, -12)]
[InlineData(-8, 4, -4)]
[InlineData(8, -4, 4)]
[InlineData(8, 4, 12)]
[InlineData(-8, 0, -8)]
[InlineData(8, 0, 8)]
[InlineData(-4, -8, -12)]
[InlineData(4, -8, -4)]
[InlineData(-4, 8, 4)]
[InlineData(4, 8, 12)]
[InlineData(0, -8, -8)]
[InlineData(0, 8, 8)]
[InlineData(1, -4, -3)]
[InlineData(1, 4, 5)]
[InlineData(1, 1, 2)]
[InlineData(-3, 1, -2)]
[InlineData(3, 1, 4)]
[InlineData(-4, 1, -3)]
[InlineData(4, 1, 5)]
[InlineData(1, -3, -2)]
[InlineData(1, 3, 4)]
[InlineData(-8, 1, -7)]
[InlineData(8, 1, 9)]
[InlineData(1, -8, -7)]
[InlineData(1, 8, 9)]
[InlineData(-1, -4, -5)]
[InlineData(-1, 4, 3)]
[InlineData(-1, -1, -2)]
[InlineData(-3, -1, -4)]
[InlineData(3, -1, 2)]
[InlineData(-4, -1, -5)]
[InlineData(4, -1, 3)]
[InlineData(-1, -3, -4)]
[InlineData(-1, 3, 2)]
[InlineData(-8, -1, -9)]
[InlineData(8, -1, 7)]
[InlineData(-1, -8, -9)]
[InlineData(-1, 8, 7)]
public void ComprehensiveAddTest(int x, int y, int expected)
{
// Act
int actual = Calculations.Add(x, y);
// Assert
Assert.Equal(expected, actual);
}
[Theory]
// Arrange
[InlineData(-3, -4, 1)]
[InlineData(-3, 4, -7)]
[InlineData(3, -4, 7)]
[InlineData(3, 4, -1)]
[InlineData(4, -4, 8)]
[InlineData(4, 4, 0)]
[InlineData(0, -4, 4)]
[InlineData(0, 4, -4)]
[InlineData(0, 0, 0)]
[InlineData(-3, 0, -3)]
[InlineData(3, 0, 3)]
[InlineData(-4, -3, -1)]
[InlineData(4, -3, 7)]
[InlineData(-4, 3, -7)]
[InlineData(4, 3, 1)]
[InlineData(-4, 4, -8)]
[InlineData(-4, 0, -4)]
[InlineData(4, 0, 4)]
[InlineData(0, -3, 3)]
[InlineData(0, 3, -3)]
[InlineData(-8, -4, -4)]
[InlineData(-8, 4, -12)]
[InlineData(8, -4, 12)]
[InlineData(8, 4, 4)]
[InlineData(-8, 0, -8)]
[InlineData(8, 0, 8)]
[InlineData(-4, -8, 4)]
[InlineData(4, -8, 12)]
[InlineData(-4, 8, -12)]
[InlineData(4, 8, -4)]
[InlineData(0, -8, 8)]
[InlineData(0, 8, -8)]
[InlineData(1, -4, 5)]
[InlineData(1, 4, -3)]
[InlineData(1, 1, 0)]
[InlineData(-3, 1, -4)]
[InlineData(3, 1, 2)]
[InlineData(-4, 1, -5)]
[InlineData(4, 1, 3)]
[InlineData(1, -3, 4)]
[InlineData(1, 3, -2)]
[InlineData(-8, 1, -9)]
[InlineData(8, 1, 7)]
[InlineData(1, -8, 9)]
[InlineData(1, 8, -7)]
[InlineData(-1, -4, 3)]
[InlineData(-1, 4, -5)]
[InlineData(-1, -1, 0)]
[InlineData(-3, -1, -2)]
[InlineData(3, -1, 4)]
[InlineData(-4, -1, -3)]
[InlineData(4, -1, 5)]
[InlineData(-1, -3, 2)]
[InlineData(-1, 3, -4)]
[InlineData(-8, -1, -7)]
[InlineData(8, -1, 9)]
[InlineData(-1, -8, 7)]
[InlineData(-1, 8, -9)]
public void ComprehensiveSubtractTest(int x, int y, int expected)
{
// Act
int actual = Calculations.Subtract(x, y);
// Assert
Assert.Equal(expected, actual);
}
[Theory]
// Arrange
[InlineData(-3, -4, 12)]
[InlineData(-3, 4, -12)]
[InlineData(3, -4, -12)]
[InlineData(3, 4, 12)]
[InlineData(4, -4, -16)]
[InlineData(4, 4, 16)]
[InlineData(0, -4, 0)]
[InlineData(0, 4, 0)]
[InlineData(0, 0, 0)]
[InlineData(-3, 0, 0)]
[InlineData(3, 0, 0)]
[InlineData(-4, -3, 12)]
[InlineData(4, -3, -12)]
[InlineData(-4, 3, -12)]
[InlineData(4, 3, 12)]
[InlineData(-4, 4, -16)]
[InlineData(-4, 0, 0)]
[InlineData(4, 0, 0)]
[InlineData(0, -3, 0)]
[InlineData(0, 3, 0)]
[InlineData(-8, -4, 32)]
[InlineData(-8, 4, -32)]
[InlineData(8, -4, -32)]
[InlineData(8, 4, 32)]
[InlineData(-8, 0, 0)]
[InlineData(8, 0, 0)]
[InlineData(-4, -8, 32)]
[InlineData(4, -8, -32)]
[InlineData(-4, 8, -32)]
[InlineData(4, 8, 32)]
[InlineData(0, -8, 0)]
[InlineData(0, 8, 0)]
[InlineData(1, -4, -4)]
[InlineData(1, 4, 4)]
[InlineData(1, 1, 1)]
[InlineData(-3, 1, -3)]
[InlineData(3, 1, 3)]
[InlineData(-4, 1, -4)]
[InlineData(4, 1, 4)]
[InlineData(1, -3, -3)]
[InlineData(1, 3, 3)]
[InlineData(-8, 1, -8)]
[InlineData(8, 1, 8)]
[InlineData(1, -8, -8)]
[InlineData(1, 8, 8)]
[InlineData(-1, -4, 4)]
[InlineData(-1, 4, -4)]
[InlineData(-1, -1, 1)]
[InlineData(-3, -1, 3)]
[InlineData(3, -1, -3)]
[InlineData(-4, -1, 4)]
[InlineData(4, -1, -4)]
[InlineData(-1, -3, 3)]
[InlineData(-1, 3, -3)]
[InlineData(-8, -1, 8)]
[InlineData(8, -1, -8)]
[InlineData(-1, -8, 8)]
[InlineData(-1, 8, -8)]
public void ComprehensiveMultiplyTest(int x, int y, int expected)
{
// Act
int actual = Calculations.Multiply(x, y);
// Assert
Assert.Equal(expected, actual);
}
[Theory]
// Arrange
[InlineData(-3, -4, 0)]
[InlineData(-3, 4, 0)]
[InlineData(3, -4, 0)]
[InlineData(3, 4, 0)]
[InlineData(4, -4, -1)]
[InlineData(4, 4, 1)]
[InlineData(0, -4, 0)]
[InlineData(0, 4, 0)]
//[InlineData(0, 0, 0)]
//[InlineData(-3, 0, 0)]
//[InlineData(3, 0, 0)]
[InlineData(-4, -3, 1)]
[InlineData(4, -3, -1)]
[InlineData(-4, 3, -1)]
[InlineData(4, 3, 1)]
[InlineData(-4, 4, -1)]
//[InlineData(-4, 0, 0)]
//[InlineData(4, 0, 0)]
[InlineData(0, -3, 0)]
[InlineData(0, 3, 0)]
[InlineData(-8, -4, 2)]
[InlineData(-8, 4, -2)]
[InlineData(8, -4, -2)]
[InlineData(8, 4, 2)]
//[InlineData(-8, 0, 0)]
//[InlineData(8, 0, 0)]
[InlineData(-4, -8, 0)]
[InlineData(4, -8, 0)]
[InlineData(-4, 8, 0)]
[InlineData(4, 8, 0)]
[InlineData(0, -8, 0)]
[InlineData(0, 8, 0)]
[InlineData(1, -4, 0)]
[InlineData(1, 4, 0)]
[InlineData(1, 1, 1)]
[InlineData(-3, 1, -3)]
[InlineData(3, 1, 3)]
[InlineData(-4, 1, -4)]
[InlineData(4, 1, 4)]
[InlineData(1, -3, 0)]
[InlineData(1, 3, 0)]
[InlineData(-8, 1, -8)]
[InlineData(8, 1, 8)]
[InlineData(1, -8, 0)]
[InlineData(1, 8, 0)]
[InlineData(-1, -4, 0)]
[InlineData(-1, 4, 0)]
[InlineData(-1, -1, 1)]
[InlineData(-3, -1, 3)]
[InlineData(3, -1, -3)]
[InlineData(-4, -1, 4)]
[InlineData(4, -1, -4)]
[InlineData(-1, -3, 0)]
[InlineData(-1, 3, 0)]
[InlineData(-8, -1, 8)]
[InlineData(8, -1, -8)]
[InlineData(-1, -8, 0)]
[InlineData(-1, 8, 0)]
public void ComprehensiveDivideTest(int x, int y, int expected)
{
// Act
int actual = Calculations.Divide(x, y);
// Assert
Assert.Equal(expected, actual);
}
}
}
Unit Tests
Description:
The homework from the Lesson 4, Unit Test Project Type, of Module 7, Common Project Types, of the Complete Foundation in C# Course Series from Tim Corey. We are to build a simple unit test project. Don't worry about testing any code yet. Just get the flow down (Arrange, Act, Assert).
Technologies Used:
- .NET;
- .NET Core;
- .NET Core 3.1;
- C#;
- Class Library;
- xUnit Test Project;
Find the Project here:
Code Snippet:
using Xunit;
namespace GreetingLibrary.Test
{
public class GreetingGeneratorTests
{
[Theory]
[InlineData("Mr.", "Corey", 0, "Good night Mr. Corey")]
[InlineData("Mr.", "Corey", 1, "Good night Mr. Corey")]
[InlineData("Mr.", "Corey", 2, "Good night Mr. Corey")]
[InlineData("Mr.", "Corey", 3, "Good night Mr. Corey")]
[InlineData("Mr.", "Corey", 4, "Good night Mr. Corey")]
[InlineData("Mr.", "Corey", 5, "Good night Mr. Corey")]
[InlineData("Mr.", "Corey", 6, "Good morning Mr. Corey")]
[InlineData("Mr.", "Corey", 7, "Good morning Mr. Corey")]
[InlineData("Mr.", "Corey", 8, "Good morning Mr. Corey")]
[InlineData("Mr.", "Corey", 9, "Good morning Mr. Corey")]
[InlineData("Mr.", "Corey", 10, "Good morning Mr. Corey")]
[InlineData("Mr.", "Corey", 11, "Good morning Mr. Corey")]
[InlineData("Mrs.", "Corey", 12, "Good afternoon Mrs. Corey")]
[InlineData("Mrs.", "Corey", 13, "Good afternoon Mrs. Corey")]
[InlineData("Mrs.", "Corey", 14, "Good afternoon Mrs. Corey")]
[InlineData("Mrs.", "Corey", 15, "Good afternoon Mrs. Corey")]
[InlineData("Mrs.", "Corey", 16, "Good afternoon Mrs. Corey")]
[InlineData("Mrs.", "Corey", 17, "Good afternoon Mrs. Corey")]
[InlineData("Mr.", "Corey", 18, "Good evening Mr. Corey")]
[InlineData("Mr.", "Corey", 19, "Good evening Mr. Corey")]
[InlineData("Mr.", "Corey", 20, "Good evening Mr. Corey")]
[InlineData("Mr.", "Corey", 21, "Good evening Mr. Corey")]
[InlineData("Mr.", "Corey", 22, "Good evening Mr. Corey")]
[InlineData("Mr.", "Corey", 23, "Good evening Mr. Corey")]
public void GreetingGeneratorTest(string prefix, string lastName, int hourOfDay, string expected)
{
// Arrange
GreetingGenerator greetings = new GreetingGenerator();
// Act
string actual = greetings.GenerateGreeting(prefix, lastName, hourOfDay);
// Assert
Assert.Equal(expected, actual);
}
}
}
Class Libraries
Description:
The homework from the Lesson 3, Class Library Project Types, of Module 7, Common Project Types, of the Complete Foundation in C# Course Series from Tim Corey. We are to build a .NET Standard Class Library and a Console Application. Put a couple calculation methods in it and call it from the Console.
Technologies Used:
- .NET;
- .NET Core;
- .NET Core 3.1;
- .NET Standard;
- .NET Standard 2.1;
- C#;
- Class Library;
- Console Application;
Find the Project here:
https://github.com/Spartan-CSharp/ProjectTypes-ClassLibraries
Code Snippet:
using System;
namespace StandardLibrary
{
public class Calculator
{
public int Add(int x, int y)
{
int output = x + y;
return output;
}
public int Subtract(int x, int y)
{
int output = x - y;
return output;
}
public int Multiply(int x, int y)
{
int output = x * y;
return output;
}
public int Divide(int x, int y)
{
int output = y != 0 ? x / y : throw new DivideByZeroException("You cannot divide by zero.");
return output;
}
public int Modulo(int x, int y)
{
int output = y != 0 ? x % y : throw new DivideByZeroException("You cannot divide by zero.");
return output;
}
}
}