From 07494d742838f3ad5a71a77e59b9e5ae999fa360 Mon Sep 17 00:00:00 2001 From: borb Date: Thu, 19 Jun 2025 17:30:55 +0300 Subject: [PATCH] finish lecture 15 --- .vscode/settings.json | 2 +- 15. Design Patterns in C#-slides.html | 167 +++++++++++++++++++++++ 15. Design Patterns in C#.md | 186 +++++++++++++------------- imgs/15 Design Patterns in C#_1.png | Bin 14164 -> 0 bytes 4 files changed, 263 insertions(+), 92 deletions(-) create mode 100644 15. Design Patterns in C#-slides.html delete mode 100644 imgs/15 Design Patterns in C#_1.png diff --git a/.vscode/settings.json b/.vscode/settings.json index 3f7eefa..b55f5c4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,7 +5,7 @@ { "match": "\\.md$", "notMatch": "README\\.md$", - "cmd": "marp ${fileDirname}\\${fileBasename} -o ${fileDirname}\\${fileBasenameNoExt}-slides.html --html true", + "cmd": "marp \"${fileDirname}\\${fileBasename}\" -o \"${fileDirname}\\${fileBasenameNoExt}-slides.html\" --html true", "useShortcut": false, "silent": false }, diff --git a/15. Design Patterns in C#-slides.html b/15. Design Patterns in C#-slides.html new file mode 100644 index 0000000..5e71d80 --- /dev/null +++ b/15. Design Patterns in C#-slides.html @@ -0,0 +1,167 @@ +15. Design Patterns in C#
+

Design Patterns in C#

+
+
+

Overview

+
    +
  • The Singleton Pattern
  • +
  • Dependency Injection
  • +
+
+
+

The Singleton Pattern

+
+
+

The problem

+
    +
  • In most cases, it makes no sense to create an instance of a class every time its members need to be accessed +
      +
    • For example, a shared resource manager that is being called from multiple classes
    • +
    +
  • +
  • While a static class could be used for this, there are some problems: +
      +
    • As stated in lecture 10, static classes can only have static members
    • +
    • Static classes cannot be instantiated, so a reference to them cannot be passed around as a parameter
    • +
    • Static classes cannot inherit from other classes or implement interfaces
    • +
    • And many more...
    • +
    +
  • +
+
+
+

The solution

+
    +
  • The singleton class is a class that benefits from all the perks of a non-static class (non-static members, inheritance, referencing…), but only one (or zero) instances of it ever exists during the lifetime of your application
  • +
  • For example, reading from / writing to a file that should be accessible to multiple clients, should be made into a singleton +
      +
    • Instead of every client directly accessing the same file (and possibly causing massive performance issues), the singleton is instantiated once and a reference to it is provided to clients
    • +
    • The singleton could take care of queueing the read/write requests and be the only entity accessing the actual file
    • +
    +
  • +
+
+
+

A singleton implementation could look something like this:

+
+
+
class Singleton
+{
+  private static Singleton instance = null;
+
+  private Singleton() { }
+  public void MySingletonFunction()
+  {
+    Console.WriteLine
+      ("This function is accessible anywhere!");
+  }
+
+  public static Singleton Instance
+  {
+    get
+    {
+      if (instance == null)
+        instance = new Singleton();
+      return instance;
+    }
+  }
+}
+
+
+
+

+class Program
+{
+  static void Main(string[] args)
+  {
+    Singleton.Instance.MySingletonFunction();
+    // Outputs: "This function is accessible
+    // from everywhere!"
+  }
+}
+
+
+
+
+
+

Implementing a singleton pattern

+
    +
  • The exact implementation of the singleton is out of the scope of this course, but it is important to understand that it exists and what its purpose is
  • +
  • Multitude of examples for different use cases are available and can be found by googling
  • +
+
+
+

Dependency Injection

+
+
+

The problem

+
    +
  • Traditionally, when new objects of classes are instantiated, the consuming class handles the creation of the objects
  • +
  • Many classes change their functionality throughout the development of any project +
      +
    • This means that also every single consuming class has to change
    • +
    • This is called tight coupling
    • +
    +
  • +
+
+
+

The solution

+
    +
  • What if, instead of directly creating the objects, they were provided by some interface that takes care of the creation?
  • +
  • This way, even if the base class changes, the consuming classes won't care because they only know about the provider
  • +
  • This provider is called Container, and the functionality being injected is called Service
  • +
  • In ASP.NET, this container system is built in
  • +
+
+
+

Dependency injection in ASP.NET

+
public class HomeController : Controller
+{
+  private readonly IUserRepository _userRepository;
+
+  public HomeController(IUserRepository userRepository)
+  {
+    _userRepository = userRepository;
+  }
+  // User repository including all users is now accessible in HomeController
+}
+
+
+
+

Design Patterns

+
    +
  • +

    If the concepts of a singleton and dependency injection flew over your head, don't worry about it

    +
  • +
  • +

    The important thing is to know they exist so that when they come up again in ASP.NET, you have already familiarized yourself with the terms

    +
      +
    • Thus, understanding the logic behind ASP.NET becomes less overwhelming
    • +
    +
  • +
  • +

    There are many more design patterns, see the material here

    +
    public void ConfigureServices(IServiceCollection services)
    +{
    +  services.AddSingleton<IDateTime, SystemDateTime>();
    +  services.AddControllersWithViews();
    +}
    +
    +
  • +
+
+
\ No newline at end of file diff --git a/15. Design Patterns in C#.md b/15. Design Patterns in C#.md index 0fd1dd7..d9897c7 100644 --- a/15. Design Patterns in C#.md +++ b/15. Design Patterns in C#.md @@ -1,133 +1,137 @@ -# Design Patterns in C# +--- +marp: true +paginate: true +math: mathjax +theme: buutti +title: 15. Design Patterns in C# +--- -![](imgs/15%20Design%20Patterns%20in%20C%23_0.png) +# Design Patterns in C# ---- + + -# Overview +## Overview -The Singleton Pattern +* The Singleton Pattern +* Dependency Injection -Dependency Injection +## The Singleton Pattern -# The Singleton Pattern +### The problem -* In some cases, it would make no sense to create an instance of a class every time it's members need to be accessed +* In most cases, it makes no sense to create an instance of a class every time its members need to be accessed * For example, a shared resource manager that is being called from multiple classes * While a static class could be used for this, there are some problems: - * As stated in the previous slide, static classes can only have static members + * As stated in [lecture 10](10.%20Static%20Members,%20Methods%20and%20Classes.md#StaticClasses), static classes can only have static members * Static classes cannot be instantiated, so a reference to them cannot be passed around as a parameter * Static classes cannot inherit from other classes or implement interfaces * [And many more... ](https://www.c-sharpcorner.com/UploadFile/akkiraju/singleton-vs-static-classes/) -# The Singleton Pattern (continued) +### The solution -* The __singleton __ class is a class that benefits from all the perks of a non-static class (non-static members, inheritance, referencing…), but only one (or zero) instances of it ever exists during the lifetime of your application +* The __singleton__ class is a class that benefits from all the perks of a non-static class (non-static members, inheritance, referencing…), but only one (or zero) instances of it ever exists during the lifetime of your application * For example, reading from / writing to a file that should be accessible to multiple clients, should be made into a singleton * Instead of every client directly accessing the same file (and possibly causing massive performance issues), the singleton is instantiated once and a reference to it is provided to clients * The singleton could take care of queueing the read/write requests and be the only entity accessing the actual file -A singleton implementation could look something like this: - -class Singleton - -{ - -private static Singleton instance = null; - -private Singleton() { } - -public void MySingletonFunction() - -{ - -Console.WriteLine - -("This function is accessible from everywhere!"); - -} - -public static Singleton Instance - -{ - -get - -{ - -if (instance == null) - -instance = new Singleton(); - -return instance; - -} +--- -} +A singleton implementation could look something like this: -} +
+
+ + ```csharp + class Singleton + { + private static Singleton instance = null; + + private Singleton() { } + public void MySingletonFunction() + { + Console.WriteLine + ("This function is accessible anywhere!"); + } + + public static Singleton Instance + { + get + { + if (instance == null) + instance = new Singleton(); + return instance; + } + } + } + ``` +
+
+ +```csharp class Program - -{ - -static void Main(string[] args) - { - -Singleton.Instance.MySingletonFunction(); - -// Outputs "This function is accessible from everywhere!" - + static void Main(string[] args) + { + Singleton.Instance.MySingletonFunction(); + // Outputs: "This function is accessible + // from everywhere!" + } } +``` +
+
-} -The exact implementation of the singleton is out of the scope of this course, but it is important to understand that it exists and what its purpose is +### Implementing a singleton pattern + +* The exact implementation of the singleton is out of the scope of this course, but it is important to understand that it exists and what its purpose is +* Multitude of examples for different use cases are available and can be found by googling -Multitude of examples for different use cases are available and can be found by googling +## Dependency Injection -# Dependency Injection +### The problem * Traditionally, when new objects of classes are instantiated, the consuming class handles the creation of the objects -* A lot of classes change their functionality throughout the development of any project +* Many classes change their functionality throughout the development of any project * This means that also _every single_ consuming class has to change - * This is called __"tight coupling"__ -* What if, instead of directly creating the objects, they were provided by some interface that takes care of the creation? - * This way, even if the base class changes, the consuming classes won't care because they only know about the provider - * This provider is called __Container, __ and the functionality being injected is called __Service__ - * In ASP.NET, this container system is built in ---- - -Show an example + * This is called *__tight coupling__* -Dependency injection in ASP.NET: - -public class HomeController : Controller +### The solution -{ - -private readonly IUserRepository \_userRepository; +* What if, instead of directly creating the objects, they were provided by some interface that takes care of the creation? +* This way, even if the base class changes, the consuming classes won't care because they only know about the provider +* This provider is called *__Container__*, and the functionality being injected is called *__Service__* +* In ASP.NET, this container system is built in -public HomeController(IUserRepository userRepository) +### Dependency injection in ASP.NET +```csharp +public class HomeController : Controller { + private readonly IUserRepository _userRepository; -\_userRepository = userRepository; - + public HomeController(IUserRepository userRepository) + { + _userRepository = userRepository; + } + // User repository including all users is now accessible in HomeController } +``` -// User repository including all users is now accessible in HomeController - -} - -# Design Patterns - -If the concepts of a singleton and dependency injection flew over your head, don't worry about it - -The important thing is to know they exist so that when they come up again in ASP.NET, you have already familiarized yourself with the terms and understanding the logic behind ASP.NET becomes less overwhelming +## Design Patterns -There are many more design patterns, see the material [here](https://www.c-sharpcorner.com/UploadFile/bd5be5/design-patterns-in-net/) +* If the concepts of a singleton and dependency injection flew over your head, don't worry about it -![](imgs/15%20Design%20Patterns%20in%20C%23_1.png) +* The important thing is to know they exist so that when they come up again in ASP.NET, you have already familiarized yourself with the terms + * Thus, understanding the logic behind ASP.NET becomes less overwhelming +* There are many more design patterns, see the material [here](https://www.c-sharpcorner.com/UploadFile/bd5be5/design-patterns-in-net/) + ```csharp + public void ConfigureServices(IServiceCollection services) + { + services.AddSingleton(); + services.AddControllersWithViews(); + } + ``` diff --git a/imgs/15 Design Patterns in C#_1.png b/imgs/15 Design Patterns in C#_1.png deleted file mode 100644 index b0d4567ce3188846417e51af3834c7da870cd8b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14164 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