├── README.adoc ├── images └── banner.png └── sessions ├── session_00 └── README.md ├── session_01 ├── .gitkeep ├── READING_MATERIAL.md ├── README_PROJECT.md ├── Slides.html ├── Slides.md ├── chirp_cli_db.csv ├── images │ ├── BDSA_git_intro_01.png │ ├── BDSA_git_intro_01.svg │ ├── BDSA_git_intro_02.png │ ├── BDSA_git_intro_03.png │ ├── BDSA_git_intro_04.png │ ├── BDSA_git_intro_05.png │ ├── BDSA_git_intro_06.png │ ├── first_names.png │ └── grades.html └── menti_results.pdf ├── session_02 ├── .gitkeep ├── READING_MATERIAL.md ├── README_PROJECT.md ├── Slides.html ├── Slides.md ├── bdsa_greeter │ ├── Makefile │ ├── Program.cs │ └── bdsa_greeter.csproj ├── hello.zip └── images │ ├── accross_pkg_dep.png │ ├── accross_pkg_dep_ui.png │ ├── git_branching_strategies.jpeg │ └── within_pkg_dep.png ├── session_03 ├── .gitkeep ├── READING_MATERIAL.md ├── README_PROJECT.md ├── Slides.html ├── Slides.md └── images │ ├── SE_TDD.png │ ├── instable_component.png │ └── stable_component.png ├── session_04 ├── .gitkeep ├── AsyncAwaitHTTP │ ├── .idea │ │ └── .idea.AsyncAwaitHTTP.dir │ │ │ └── .idea │ │ │ ├── .gitignore │ │ │ ├── encodings.xml │ │ │ ├── indexLayout.xml │ │ │ └── vcs.xml │ └── src │ │ ├── Client │ │ ├── Client.csproj │ │ └── Program.cs │ │ └── Server │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── Server.csproj │ │ ├── appsettings.Development.json │ │ └── appsettings.json ├── READING_MATERIAL.md ├── README_PROJECT.md ├── Slides.html ├── Slides.md └── images │ ├── client_server_comp.png │ ├── client_server_comp_db.png │ ├── client_server_seq.png │ ├── client_server_seq_db.png │ ├── db_schema.png │ ├── deployment.png │ ├── inspector.png │ ├── middleware.png │ └── multi_clients_server_comp.png ├── session_05 ├── .gitkeep ├── Chirp.SQLite │ ├── .vscode │ │ ├── launch.json │ │ └── tasks.json │ ├── Chirp.SQLite.csproj │ ├── Program.cs │ ├── data │ │ ├── dump.sql │ │ └── schema.sql │ └── scripts │ │ └── initDB.sh ├── DIExample │ ├── DIExample.csproj │ ├── DirectDependency.cs │ ├── InjectedDependency.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Writer.cs │ ├── appsettings.Development.json │ └── appsettings.json ├── READING_MATERIAL.md ├── README_PROJECT.md ├── SimpleHTMLServer │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── SimpleHTMLServer.csproj │ ├── appsettings.Development.json │ └── appsettings.json ├── Slides.html ├── Slides.md ├── data │ ├── dump.sql │ └── schema.sql ├── images │ ├── accross_pkg_dep.png │ ├── direct_dep.png │ ├── inversed_dep.png │ ├── simpledb_deployment.png │ ├── sqlite_deployment.png │ └── ssr_sq.png └── scripts │ └── initDB.sh ├── session_06 ├── .gitkeep ├── Feedback.html ├── Feedback.md ├── READING_MATERIAL.md ├── README_PROJECT.md ├── Slides.html ├── Slides.md ├── data │ └── DbInitializer.cs └── images │ ├── .png │ ├── CS-to-db-changed.svg │ ├── CS-to-db.svg │ ├── DBContext.svg │ ├── EF-Core.png │ ├── ORM-overview.png │ ├── Repository.svg │ ├── azure_logs.png │ ├── banner-transparent.png │ ├── commit_freqs.png │ ├── domain_model.svg │ ├── repository-pattern.png │ └── unit-of-work.png ├── session_07 ├── .gitkeep ├── READING_MATERIAL.md ├── README_PROJECT.md ├── Slides.html ├── Slides.md └── images │ ├── Onion-Diagram-a.svg │ ├── Onion-Diagram-b.svg │ ├── Onion-Diagram.svg │ ├── banner-transparent.png │ ├── domain_model.png │ ├── domain_model_constrained.png │ ├── entity-framework-core.jpg │ ├── fake-provider-and-repository-pattern.png │ ├── onion_architecture.webp │ └── unit-of-work-diagram.png ├── session_08 ├── .gitkeep ├── READING_MATERIAL.md ├── README_PROJECT.md ├── Slides.html ├── Slides.md └── images │ ├── Oauth_logo.svg │ ├── arduino-login.png │ ├── authentication_login.png │ ├── authentication_subsequent.png │ ├── banner-transparent.png │ ├── chirp_after_auth.png │ ├── chirp_before_auth.png │ ├── claims_principle.png │ ├── cookie-basic-example.png │ ├── cookie-monster.png │ ├── domain_model.svg │ ├── domain_model_with_identity.svg │ ├── gh_oauth_local_config.png │ ├── github-oauth-settings.png │ ├── oauth_azure_config.png │ ├── oauth_dance-chirp-authenticate.png │ ├── oauth_dance-redirect.png │ ├── oauth_dance-resource-access.png │ ├── oauth_dance-user-authenticate.png │ ├── oauth_dance.png │ └── oauth_dance.psd ├── session_09 ├── .gitkeep ├── Feedback.html ├── Feedback.md ├── READING_MATERIAL.md ├── README_PROJECT.md ├── Slides.html ├── Slides.md └── images │ ├── HTML form UI.png │ ├── Playwright recording.png │ ├── banner-transparent.png │ └── request-handling-razor-pages.png ├── session_10 ├── .gitkeep ├── Git_Crash_Course_by_daso.pdf ├── READING_MATERIAL.md ├── README_PROJECT.md ├── Slides.html ├── Slides.md └── images │ ├── CDN.jpg │ ├── CSRF-1.png │ ├── CSRF-2.png │ ├── CSRF-3.png │ ├── CSRF-4.png │ ├── CSRF.png │ ├── CSRF.psd │ ├── XSS-attack.png │ ├── XSS-result-protected-rendered.png │ ├── XSS-result-protected.png │ ├── XSS-result-unprotected-rendered.png │ ├── XSS-result-unprotected.png │ ├── banner-transparent.png │ ├── http-unencrypted.png │ ├── https-decision-diagram.svg │ ├── https-encrypted.png │ ├── https-hsts.png │ ├── https-locally-browser.png │ ├── https-offloading.png │ ├── https-passthrough.png │ ├── https-redirects.png │ ├── load-testing.png │ ├── owasp-top-ten.png │ └── xkcd-bobby-tables.png ├── session_11 ├── .gitkeep ├── READING_MATERIAL.md ├── README_PROJECT.md ├── Slides.html ├── Slides.md └── images │ ├── accross_pkg_dep_ui.png │ ├── activity.png │ ├── activity_syntax.png │ ├── authenticated_request.png │ ├── bpmn.png │ ├── bpmn_legend.png │ ├── class.png │ ├── class_association.png │ ├── class_inheritance.png │ ├── client_server_comp_db.png │ ├── domain_model.png │ ├── domain_model_constrained.png │ ├── feature_model.png │ ├── login_logout_sm.png │ ├── multi_clients_server_comp.png │ ├── non_func_reqs.png │ ├── non_func_reqs2.png │ ├── sd_call.png │ ├── sd_oauth_dance.png │ ├── state_follow.png │ ├── wireframe.png │ └── wireframe_online_editor.png ├── session_12 ├── .gitkeep ├── READING_MATERIAL.md ├── README_PROJECT.md ├── README_REPORT.md ├── Slides.html ├── Slides.md └── docs │ ├── images │ └── domain_model.png │ └── report.md └── session_13 ├── .gitkeep ├── README_PROJECT.md ├── Slides.html └── Slides.md /images/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/images/banner.png -------------------------------------------------------------------------------- /sessions/session_00/README.md: -------------------------------------------------------------------------------- 1 | The following describes what we would like you to do before the first session of the course _Analysis, Design and Software Architecture_ on Wednesday, Aug. 28th (10:00). 2 | 3 | We would like that you prepare the following three things: 4 | 5 | * [A) Survey](#A-survey) 6 | * [B) Register accounts](#B-register-accounts) 7 | * [C) Setup workstation](#C-setup-workstation) 8 | 9 | In case you have problems with installation of any of the tools, do not despair. 10 | You will be able to ask the TAs for help during the first exercise session on Wednesday, Aug. 28th (14:00). 11 | 12 | ------------------------------------------------------------------------------- 13 | 14 | # A) Survey 15 | 16 | Please fill out the survey on menti.com, which will allow us to better adapt our teaching to you. 17 | The link is shared with you in a message that you received via LearnIT and via our Teams channel. 18 | 19 | ------------------------------------------------------------------------------- 20 | 21 | # B) Register accounts 22 | 23 | ## Create an account on [GitHub](https://github.com) 24 | 25 | If you do not have an account on [GitHub](https://github.com) yet, sign-up via https://github.com/signup 26 | 27 | Note, in this course we are using [GitHub.com](https://github.com) **not** [ITU's GitHub instance](https://github.itu.dk/). 28 | 29 | 30 | ## GitHub Student Developer Pack 31 | 32 | Sign up for the [GitHub Student Developer Pack](https://education.github.com/experiences/virtual_event_kit) to receive free credit for Azure services. 33 | Some of which, we will use later in the course. 34 | 35 | 36 | -------------------------------------------------------------------------------- 37 | 38 | # C) Setup workstation 39 | 40 | ## Install a package manager 41 | 42 | - Windows 43 | - You should have [winget](https://docs.microsoft.com/en-us/windows/package-manager/winget/) already installed. If not make sure to install it. 44 | - MacOS 45 | - Install [homebrew](https://brew.sh/) by running the following in your terminal: 46 | 47 | ```bash 48 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 49 | ``` 50 | - Linux 51 | - Depending on your distribution, you have a package manager like `apt` (Debian-based distributions) or `rpm` (RedHat-based distributions), etc. already installed. 52 | 53 | ## Install software (latest versions) 54 | 55 | 1. Windows only: 56 | 1. [Windows Terminal](https://docs.microsoft.com/en-us/windows/terminal/) 57 | 2. [Custom prompt](https://docs.microsoft.com/en-us/windows/terminal/tutorials/custom-prompt-setup) 58 | 3. [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/) with Ubuntu 59 | 2. [Git](https://git-scm.com/downloads) 60 | 3. [.NET **7**](https://dotnet.microsoft.com/en-us/download/dotnet/7.0) 61 | - If your operating, sytstem is Windows install .NET 7 in WSL 62 | 4. A full IDE: 63 | - [JetBrains Rider](https://www.jetbrains.com/rider/) (all operating systems) Note, you can get a free student license for all JetBrais IDEs that you use during your education, see 64 | - *Optionally* [Visual Studio Community](https://visualstudio.microsoft.com/downloads/) (Windows and Mac only) 65 | 5. *Optionally* [Visual Studio Code](https://code.visualstudio.com/Download) with extensions: 66 | - [C#](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp) 67 | - [.NET Core Test Explorer](https://marketplace.visualstudio.com/items?itemName=formulahendry.dotnet-test-explorer) 68 | - [Remote Development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack) 69 | - [REST Client](https://marketplace.visualstudio.com/items?itemName=humao.rest-client) 70 | -------------------------------------------------------------------------------- /sessions/session_01/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_01/.gitkeep -------------------------------------------------------------------------------- /sessions/session_01/READING_MATERIAL.md: -------------------------------------------------------------------------------- 1 | # Reading Material for Session 01 2 | 3 | 4 | ## About Git 5 | 6 | * In case you are in doubt about any of the basic Git command, see [section 2 of the Pro Git book](https://git-scm.com/book/en/v2/Git-Basics-Getting-a-Git-Repository). 7 | * [A visual explanation of various Git commands](https://onlywei.github.io/explain-git-with-d3/) 8 | * [A Visual Git Reference](https://marklodato.github.io/visual-git-guide/index-en.html) 9 | * [A Git Beginner Reference Guide](https://mukulrathi.com/git-beginner-cheatsheet/) 10 | 11 | 12 | ## Help on C♯ 13 | 14 | * [Introduction to C♯](https://learn.microsoft.com/en-us/dotnet/csharp/) 15 | - [A tour of the C♯ language](https://learn.microsoft.com/en-us/dotnet/csharp/tour-of-csharp/) 16 | - [The C♯ type system](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/types/) 17 | - [Description of C♯ top-level statements](https://learn.microsoft.com/en-us/dotnet/core/tutorials/top-level-templates) 18 | * [.NET Naming Guidelines](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/naming-guidelines) 19 | 20 | 21 | ## Debugging 22 | 23 | * [Debugging in JetBrains Rider](https://www.jetbrains.com/help/rider/Debugging_Code.html) 24 | * [Debugging in Visual Studio Code](https://code.visualstudio.com/Docs/editor/debugging) 25 | -------------------------------------------------------------------------------- /sessions/session_01/chirp_cli_db.csv: -------------------------------------------------------------------------------- 1 | Author,Message,Timestamp 2 | ropf,"Hello, BDSA students!",1690891760 3 | adho,"Welcome to the course!",1690978778 4 | adho,"I hope you had a good summer.",1690979858 5 | ropf,"Cheeping cheeps on Chirp :)",1690981487 6 | -------------------------------------------------------------------------------- /sessions/session_01/images/BDSA_git_intro_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_01/images/BDSA_git_intro_01.png -------------------------------------------------------------------------------- /sessions/session_01/images/BDSA_git_intro_01.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | Produced by OmniGraffle 7.18.6\n2024-08-27 10:07:35 +0000 22 | 23 | Canvas 1 24 | 25 | 26 | Layer 1 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | commit 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | tree 83 | 84 | 85 | 86 | 87 | parent 88 | 89 | 90 | 91 | 92 | author 93 | 94 | 95 | 96 | 97 | committer 98 | 99 | 100 | 101 | 102 | f40beda2 103 | 104 | 105 | 106 | 107 | Initial commit 108 | 109 | 110 | 111 | 112 | 359b5b4a 113 | 114 | 115 | 116 | 117 | HelgeCPH <ropf@itu.dk> 118 | 119 | 120 | 121 | 122 | HelgeCPH <ropf@itu.dk> 123 | 124 | 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /sessions/session_01/images/BDSA_git_intro_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_01/images/BDSA_git_intro_02.png -------------------------------------------------------------------------------- /sessions/session_01/images/BDSA_git_intro_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_01/images/BDSA_git_intro_03.png -------------------------------------------------------------------------------- /sessions/session_01/images/BDSA_git_intro_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_01/images/BDSA_git_intro_04.png -------------------------------------------------------------------------------- /sessions/session_01/images/BDSA_git_intro_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_01/images/BDSA_git_intro_05.png -------------------------------------------------------------------------------- /sessions/session_01/images/BDSA_git_intro_06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_01/images/BDSA_git_intro_06.png -------------------------------------------------------------------------------- /sessions/session_01/images/first_names.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_01/images/first_names.png -------------------------------------------------------------------------------- /sessions/session_01/images/grades.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Grades plot 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
38 | 39 | 40 | 41 | 42 | 43 | 46 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /sessions/session_01/menti_results.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_01/menti_results.pdf -------------------------------------------------------------------------------- /sessions/session_02/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_02/.gitkeep -------------------------------------------------------------------------------- /sessions/session_02/READING_MATERIAL.md: -------------------------------------------------------------------------------- 1 | # Reading Material for Session 02 2 | 3 | ## Collaborative Work (on GitHub) 4 | 5 | * Read [chapter 9 on Teamwork from Mark Seemann's _Code That Fits in Your Head_](https://ituniversity.sharepoint.com/:b:/r/sites/2024AnalysisDesignandSoftwareArchitecture/Shared%20Documents/General/Documents/code-that-fits-your-head_ch9_scan.pdf?csf=1&web=1&e=LSaXUp) 6 | * How to use [issues](https://docs.github.com/issues) and [projects](https://docs.github.com/en/issues/planning-and-tracking-with-projects) on GitHub 7 | * More details [about GitHub issues](https://docs.github.com/en/issues/tracking-your-work-with-issues/about-issues) 8 | * More details [about GitHub projects](https://docs.github.com/en/issues/planning-and-tracking-with-projects/learning-about-projects/about-projects) 9 | 10 | 11 | ## C♯ Language Features 12 | 13 | * [`record` reference types in C♯](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record) 14 | * [Generics in C♯](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/types/generics) 15 | 16 | 17 | ## Building C♯/.NET Projects 18 | 19 | * [Publish .NET applications with the .NET CLI](https://learn.microsoft.com/en-us/dotnet/core/deploying/deploy-with-cli) 20 | * [Single-file deployments](https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview?tabs=cli) 21 | * Official documentation on the CLI commands 22 | - [`dotnet run`](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-run) 23 | - [`dotnet build`](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-build) 24 | - [`dotnet clean`](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-clean) 25 | - [`dotnet publish`](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-publish) 26 | * [Training material for handling external dependencies](https://learn.microsoft.com/en-us/training/modules/dotnet-dependencies/) 27 | 28 | 29 | ## Parsing CLI Arguments and Options 30 | 31 | * Using: [`System.CommandLine`](https://learn.microsoft.com/en-us/archive/msdn-magazine/2019/march/net-parse-the-command-line-with-system-commandline) 32 | * Using: [`CommandLine`](https://github.com/commandlineparser/commandline) 33 | * Using: [`docopt.net`](https://docopt.github.io/docopt.net/dev/) 34 | 35 | ## Diagrams 36 | 37 | * [UML class diagrams](https://www.uml-diagrams.org/class-diagrams-overview.html) 38 | https://www.uml-diagrams.org/class.html 39 | -------------------------------------------------------------------------------- /sessions/session_02/README_PROJECT.md: -------------------------------------------------------------------------------- 1 | # Your turn now! -- Project Work 2 | 3 | 4 | 5 | You have to work on the following topics. 6 | 7 | - [1) Process](#1-process) 8 | - [2) Software Development](#2-software-development) 9 | - [3) Ethics](#3-ethics) 10 | 11 | Remember, you have to perform work on each topic and on **each** bullet point. 12 | Be done with the project work before we meet again next week's lecture. 13 | 14 | 15 | ## 1) Process 16 | 17 | * From now on, organize your project work into issues (tickets) on GitHub. 18 | Describe each issue drawing inspiration from the guidelines presented in class. 19 | - Issues shall describe the tasks presented in the `README_PROJECT.md` files. 20 | Add additional issues for tasks that you identify to complete your project work. 21 | - Make sure that you label your issues according to their type, e.g., do they describe a new feature, an enhancement, a bug, etc. 22 | * From now on, make sure that you record your work in multiple _small_ commits. 23 | Not one big one per task, as suggested by Mark Seeman in the [reading material](READING_MATERIAL.md#collaborative-work-(on-github)). 24 | - Remember, to register all co-authors that contributed to a commit, see session 01. 25 | - Each co-author is registered on a separate line in the commit message, see [feedback in lecture notes](Slides.md#feedback-III). 26 | - Make all these small commits in short-lived feature branches, which you merge with main (at least once per day). 27 | * From now on, use a GitHub project board to organize your work and to make your work status visible. 28 | - Use the project template called _"Team planning"_, i.e., use the _board layout_ (not the table or project layout). 29 | - Add all issues that you might have already created to the project board, this can be done [manually](https://docs.github.com/en/issues/planning-and-tracking-with-projects/managing-items-in-your-project/adding-items-to-your-project#bulk-adding-issues-and-pull-requests) or [automatically](https://docs.github.com/en/issues/planning-and-tracking-with-projects/automating-your-project/adding-items-automatically). 30 | - Make sure that the status of the issues is properly reflected in the project board, i.e., move issues that are work-in-progress to the respective column, etc. 31 | 32 | 33 | ## 2) Software Development 34 | 35 | The following are separate tasks. 36 | That is, treat them as such. 37 | Even though it might tempting to perform all the refactorings in one big chunk of work, train to work on separate concerns, one at a time. 38 | 39 | 40 | ### 2.a) Refactor _Chirp!_ to use an external library for CSV file handling 41 | 42 | In general, comprehensive support for CSV files with correct handling of escape characters, line breaks, etc. is quite difficult. 43 | In case you are using "manual" parsing and unparsing of comma-separated values when receiving and storing cheeps to and from disk, refactor your implementation of _Chirp!_ so that it uses a library that handles CSV files properly. 44 | One of the most used libraries for handling CSV files in C♯ seems to be [`CsvHelper`](https://joshclose.github.io/CsvHelper/getting-started/). 45 | Use this or a [comparable library](https://www.nuget.org/packages?q=CSV&frameworks=&tfms=&packagetype=&prerel=true) to read cheeps from and write cheeps to a CSV file. 46 | 47 | For now, cheeps shall be objects that are instances of a respective [`record`](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record) that was presented in class: 48 | 49 | ```csharp 50 | public record Cheep(string Author, string Message, long Timestamp); 51 | ``` 52 | 53 | 54 | ### 2.b) Refactor data persistence to library project `SimpleDB` 55 | 56 | Refactor the entire data persistence solution so that it resides in a library project `SimpleDB` on which your `Chirp.CLI` project depends, see [the official documentation on how to establish references between projects](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-add-reference). 57 | 58 | Create a new .NET `classlib` project called `SimpleDB` (or reuse the one from class) and create a class `CSVDatabase` in it that implements the `IDatabaseRepository` that was presented in the lecture. 59 | Note, it shall not be possible to create further sub-classes of class `CSVDatabase`, see [the official documentation on how to achieve that](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/sealed). 60 | 61 | Make sure that your `SimpleDB` relies on the refactored code from the task above, i.e., that it depends on an external library for parsing and unparsing of CSV data. 62 | 63 | Note, after this refactoring, your `Chirp.CLI` project is likely quite "slim" and contains only code for retrieving command-line arguments and for printing output, i.e., it contains the application's user interface. 64 | 65 | When illustrated as UML class diagram, your current program (the one that you created in last week's project work) looks likely as on the left below. That is, all functionality is contained in a single `Program` class, which is contained in your `Program.cs` file. 66 | 67 | After the refactoring, it should look as on the right below. That is, a generic class `CSVDatabase` implements the generic interface `IDatabaseRepository` and the two methods `Read` and `Store`. A reference to the `database` is used in the main program class so that cheeps can be stored to the database and be retrieved from it. 68 | 69 | | Before refactoring | After refactoring | 70 | |:-------------------------------:|:------------------------------:| 71 | | ![](images/within_pkg_dep.png ) | ![](images/accross_pkg_dep.png)| 72 | 73 | 74 | ### 2.c) Refactor `Chirp.CLI`'s `Program.cs` so that all User Interface code resides in a separate class 75 | 76 | Refactor all code that is concerned with printing cheeps to the terminal into a separate class called `UserInterface`. That is, after refactoring, your main program depends on this new class and calls a respective method whenever cheeps are printed to the terminal. 77 | 78 | Likely, it is a good design to make the UserInterface and the contained methods [`static`](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-classes-and-static-class-members) 79 | 80 | | Before refactoring | After refactoring | 81 | |:--------------------------------:|:---------------------------------:| 82 | | ![](images/accross_pkg_dep.png ) | ![](images/accross_pkg_dep_ui.png)| 83 | 84 | 85 | ### 2.d) Refactor `Chirp.CLI`'s `Program.cs` to use an external library CLI interface 86 | 87 | Proper parsing of arguments and options that are provided to a program is difficult and error prone. 88 | Therefore, refactor your current `Program.cs` so that arguments passed to the program are not manually parsed out of the `args` property. 89 | 90 | You may want to choose [`System.CommandLine`](https://learn.microsoft.com/en-us/archive/msdn-magazine/2019/march/net-parse-the-command-line-with-system-commandline), [`CommandLine`](https://github.com/commandlineparser/commandline), [`docopt.net`](https://docopt.github.io/docopt.net/dev/), or any other comparable library that you find on [nuget.org](https://www.nuget.org/). 91 | 92 | 93 | ## 3) Ethics 94 | 95 | Consider if want to share telemetry data with Microsoft. Per default, Microsoft collects data about many actions that you perform using their tools, see e.g., https://learn.microsoft.com/en-us/dotnet/core/tools/telemetry and https://dotnet.microsoft.com/en-us/platform/telemetry. 96 | 97 | You can disable telemetry when using the `dotnet` command by creating an environment variable (in your `.bashrc` or whichever shell you are using) before invoking any `dotnet` commands: 98 | 99 | * `DOTNET_CLI_TELEMETRY_OPTOUT=1` or 100 | * `DOTNET_CLI_TELEMETRY_OPTOUT=true` 101 | 102 | 103 | Additionally, VSCode collects telemetry data on how you are using it. 104 | You might want to disable that in the settings (set `telemetry.telemetryLevel` to off), see https://code.visualstudio.com/docs/getstarted/telemetry. 105 | 106 | 107 | **OBS:** In general, when you build software in your later professional lives, it is a good practice to make collection of telemetry opt-in and not opt-out. 108 | -------------------------------------------------------------------------------- /sessions/session_02/bdsa_greeter/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all build clean 2 | 3 | all: build 4 | 5 | bin/Release/net7.0/linux-x64/publish/hello: Program.cs bdsa_greeter.csproj 6 | dotnet publish -r linux-x64 7 | 8 | bin/Release/net7.0/win-x64/publish/hello.exe: Program.cs bdsa_greeter.csproj 9 | dotnet publish -r win-x64 10 | 11 | bin/Release/net7.0/win-arm64/publish/hello.exe: Program.cs bdsa_greeter.csproj 12 | dotnet publish -r win-arm64 13 | 14 | bin/Release/net7.0/osx-x64/publish/hello: Program.cs bdsa_greeter.csproj 15 | dotnet publish -r osx-x64 16 | 17 | bin/Release/net7.0/osx-arm64/publish/hello: Program.cs bdsa_greeter.csproj 18 | dotnet publish -r osx-arm64 19 | 20 | build: bin/Release/net7.0/linux-x64/publish/hello bin/Release/net7.0/win-x64/publish/hello.exe bin/Release/net7.0/win-arm64/publish/hello.exe bin/Release/net7.0/osx-x64/publish/hello bin/Release/net7.0/osx-arm64/publish/hello 21 | 22 | clean: 23 | rm -r ./bin/ ./obj/ 24 | -------------------------------------------------------------------------------- /sessions/session_02/bdsa_greeter/Program.cs: -------------------------------------------------------------------------------- 1 | // Project was generated on Linux with: 2 | // dotnet new console --framework net6.0 3 | 4 | // Nice message is generated here: 5 | // https://patorjk.com/software/taag/#p=display&f=Bloody&t=Welcome%0A%20%20%20%20%20%20%20to%0A%20%20%20%20%20%20ITU 6 | string msg = @" 7 | █ █░▓█████ ██▓ ▄████▄ ▒█████ ███▄ ▄███▓▓█████ 8 | ▓█░ █ ░█░▓█ ▀ ▓██▒ ▒██▀ ▀█ ▒██▒ ██▒▓██▒▀█▀ ██▒▓█ ▀ 9 | ▒█░ █ ░█ ▒███ ▒██░ ▒▓█ ▄ ▒██░ ██▒▓██ ▓██░▒███ 10 | ░█░ █ ░█ ▒▓█ ▄ ▒██░ ▒▓▓▄ ▄██▒▒██ ██░▒██ ▒██ ▒▓█ ▄ 11 | ░░██▒██▓ ░▒████▒░██████▒▒ ▓███▀ ░░ ████▓▒░▒██▒ ░██▒░▒████▒ 12 | ░ ▓░▒ ▒ ░░ ▒░ ░░ ▒░▓ ░░ ░▒ ▒ ░░ ▒░▒░▒░ ░ ▒░ ░ ░░░ ▒░ ░ 13 | ▒ ░ ░ ░ ░ ░░ ░ ▒ ░ ░ ▒ ░ ▒ ▒░ ░ ░ ░ ░ ░ ░ 14 | ░ ░ ░ ░ ░ ░ ░ ░ ░ ▒ ░ ░ ░ 15 | ░ ░ ░ ░ ░░ ░ ░ ░ ░ ░ ░ 16 | ░ 17 | ▄▄▄█████▓ ▒█████ 18 | ▓ ██▒ ▓▒▒██▒ ██▒ 19 | ▒ ▓██░ ▒░▒██░ ██▒ 20 | ░ ▓██▓ ░ ▒██ ██░ 21 | ▒██▒ ░ ░ ████▓▒░ 22 | ▒ ░░ ░ ▒░▒░▒░ 23 | ░ ░ ▒ ▒░ 24 | ░ ░ ░ ░ ▒ 25 | ░ ░ 26 | 27 | ██▓▄▄▄█████▓ █ ██ 28 | ▓██▒▓ ██▒ ▓▒ ██ ▓██▒ 29 | ▒██▒▒ ▓██░ ▒░▓██ ▒██░ 30 | ░██░░ ▓██▓ ░ ▓▓█ ░██░ 31 | ░██░ ▒██▒ ░ ▒▒█████▓ 32 | ░▓ ▒ ░░ ░▒▓▒ ▒ ▒ 33 | ▒ ░ ░ ░░▒░ ░ ░ 34 | ▒ ░ ░ ░░░ ░ ░ 35 | ░ ░ 36 | 37 | "; 38 | Console.WriteLine(msg); 39 | -------------------------------------------------------------------------------- /sessions/session_02/bdsa_greeter/bdsa_greeter.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net7.0 6 | enable 7 | enable 8 | 9 | true 10 | true 11 | false 12 | embedded 13 | hello 14 | win-x64;win-arm64;linux-x64;osx-x64;osx-arm64 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /sessions/session_02/hello.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_02/hello.zip -------------------------------------------------------------------------------- /sessions/session_02/images/accross_pkg_dep.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_02/images/accross_pkg_dep.png -------------------------------------------------------------------------------- /sessions/session_02/images/accross_pkg_dep_ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_02/images/accross_pkg_dep_ui.png -------------------------------------------------------------------------------- /sessions/session_02/images/git_branching_strategies.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_02/images/git_branching_strategies.jpeg -------------------------------------------------------------------------------- /sessions/session_02/images/within_pkg_dep.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_02/images/within_pkg_dep.png -------------------------------------------------------------------------------- /sessions/session_03/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_03/.gitkeep -------------------------------------------------------------------------------- /sessions/session_03/READING_MATERIAL.md: -------------------------------------------------------------------------------- 1 | # Reading Material for Session 03 2 | 3 | ## Testing 4 | 5 | * Read chapters 35 and 36 from [Andrew Lock _ASP.NET Core in Action, Third Edition_](https://www.manning.com/books/asp-net-core-in-action-third-edition) 6 | * [Introduction to Unit Testing from official documentation](https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-with-dotnet-test) 7 | * [Organize .NET Project for testing](https://learn.microsoft.com/en-us/dotnet/core/tutorials/testing-with-cli) 8 | * [Testing best practices](https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices) 9 | 10 | 11 | ## GitHub Actions 12 | 13 | * [Introduction to GitHub Actions from Microsoft Trainings Center](https://learn.microsoft.com/en-us/training/modules/introduction-to-github-actions) 14 | * [GitHub's official documentation of GitHub Actions](https://docs.github.com/actions) 15 | * [Microsoft's official documentation of GitHub Actions for .NET projects](https://learn.microsoft.com/en-us/dotnet/devops/github-actions-overview) 16 | * [A blog post that provides an example of how to release binaries](https://patriksvensson.se/posts/2020/03/creating-release-artifacts-with-github-actions) 17 | 18 | 19 | ## Singleton Pattern 20 | 21 | * [_C♯ in Depth_](https://csharpindepth.com/Articles/Singleton)'s description of various implementations of the Singleton Pattern in C♯ 22 | * [An alternative description of it with examples](https://refactoring.guru/design-patterns/singleton) 23 | 24 | 25 | 26 | 27 | 30 | -------------------------------------------------------------------------------- /sessions/session_03/README_PROJECT.md: -------------------------------------------------------------------------------- 1 | # Your turn now! -- Project Work 2 | 3 | 4 | 5 | You have to work on the following topics. 6 | 7 | - [1) Process](#1-process) 8 | - [2) Software Development](#2-software-development) 9 | - [3) Ethics](#3-ethics) 10 | - [4) Prepare for next session](#4-prepare-for-next-session) 11 | 12 | Remember, you have to perform work on each topic and on **each** bullet point. 13 | Be done with the project work before we meet again next Thursday. 14 | 15 | 16 | ## 1) Process 17 | 18 | ### 1.a) Automate build, test, and publishing with GitHub Workflows 19 | 20 | Add GitHub Actions workflows to your projects. 21 | Likely, you will add two or more of them. 22 | 23 | * Start with adding an adapted version of a [.NET starter workflow](https://github.com/actions/starter-workflows/blob/main/ci/dotnet.yml). 24 | - When adapting it, make sure that you are using a .NET version 7, the same that we told you to install on your local computers. 25 | - That workflow shall be executed on all pushes and merge of pull-requests in your repository. 26 | * Add a workflow that releases your `chirp` executable, i.e., a single file .NET application. 27 | - The workflow should build and test your project whenever you push a new version that is accordingly tagged ([`git tag`](https://git-scm.com/book/en/v2/Git-Basics-Tagging)) to your repository. 28 | - When all tests pass, create at least three executables of your _Chirp!_ project, one for Windows, one for MacOS, and one for Linux (`-x64`). 29 | - If you want to, publish executables for ARM processors too. 30 | - Each executable shall be distributed as compressed with `zip` file. 31 | - All of the above steps shall be executed in an `ubuntu-latest` environment, i.e., you want to cross-compile for the different targets. 32 | - Since everybody in this course has .NET 7 installed it is sufficient to publish a platform-dependent single file application, i.e., not a self-contained application. 33 | 34 | ### Hints: 35 | 36 | * Likely you can combine the building blocks from the lecture notes and the reading material into a working solution. 37 | * To publish a release of your project, you might want to use the [`softprops/action-gh-release` action](https://github.com/softprops/action-gh-release) 38 | * You might use this [blog post](https://patriksvensson.se/posts/2020/03/creating-release-artifacts-with-github-actions) for inspiration on how to create releases for various operating systems. Note though, that you want to build in one environment (`ubuntu-latest`) instead of three as in the given example, i.e., you do not need a build matrix. 39 | * To allow a GitHub action to create releases, you have to grant it write access. You do that on GitHub in your repository under `Settings` → `Actions` → `General` under `Workflow permissions` enable `"Read and write permissions"`, see the [official documentation](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#setting-the-permissions-of-the-github_token-for-your-repository) 40 | 41 | ### 1.b) Automate certain project management tasks 42 | 43 | Using GitHub Actions, you can [automate certain tasks](https://docs.github.com/en/actions/managing-issues-and-pull-requests/using-github-actions-for-project-management), like [adding labels to issues](https://docs.github.com/en/actions/managing-issues-and-pull-requests/adding-labels-to-issues), [moving labels to project board columns on state change](https://docs.github.com/en/actions/managing-issues-and-pull-requests/moving-assigned-issues-on-project-boards), etc. 44 | Choose some of these project management tasks that you deem suitable and automate the with GitHub Actions workflow. 45 | 46 | ### 1.c) Enable automatic code formatting 47 | 48 | Make sure that everybody in the team formats code whenever it is edited with Rider. 49 | The IDE supports this by default, the [respective configuration needs to be activated](https://www.jetbrains.com/help/rider/Enforcing_Code_Formatting_Rules.html). 50 | 51 | 52 | ## 2) Software Development 53 | 54 | ### 2.a) Software Testing 55 | 56 | * Restructure your current project so that the _Chirp!_ application and the CSV database library reside under a `src/` directory 57 | - Hint: use `git mv` to move files and directories while restructuring. 58 | * Create XUnit .NET test projects, see `dotnet new list` in a `test` directory that is in the root of your project, see e.g., page 880 of A. Lock _ASP.NET Core in Action, Third Edition_. 59 | - That is, one test project that tests your _Chirp!_ CLI app and a second one that tests your CSV database library project. 60 | * Make your test projects depend on the respective system under test (SUT). 61 | - That is, add a reference from each of the two test projects to either the _Chirp!_ CLI app or to the CSV database library project with the [`dotnet add reference`](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-add-reference) command. 62 | * Add unit tests to your _Chirp!_ CLI app. 63 | - Add unit tests for suitable functionality. For example, conversion of UNIX timestamps to user readable times and similar functionality are good candidates for unit testing. 64 | * Add integration tests that test your CSV database library works as intended. 65 | - For example, add a test case that checks that an entry can be received from the database after it was stored in there. 66 | * Add two end-to-end tests that test your _Chirp!_ CLI app: 67 | - For example, you want to test that given example data from [`chirp_cli_db.csv`](../session_01/chirp_cli_db.csv) calling `chirp read 10` from the command line produces output as in the following: 68 | ``` 69 | ropf @ 08/01/23 14:09:20: Hello, BDSA students! 70 | rnie @ 08/02/23 14:19:38: Welcome to the course! 71 | rnie @ 08/02/23 14:37:38: I hope you had a good summer. 72 | ropf @ 08/02/23 15:04:47: Cheeping cheeps on Chirp :) 73 | ``` 74 | - Additionally, you want to test that calling `chirp cheep "Hello!!!"` stores the respective values in the database. 75 | 76 | ### 2.b) Software Design 77 | 78 | We want to be able to express and to assure that there is at any given point in time only one CSV database on our system. 79 | That is we want to couple the database CSV file on the file system to a singleton object in our software. 80 | Consequently, refactor your `CSVDatabase` class that is responsible for `Read`ing cheeps from and `Store`ing cheeps to a CSV file to be a _singleton_. 81 | That is, make it adhere to the singleton design pattern. 82 | Likely, it is a good idea to skim the various implementations that are presented in [C♯ in Depth](https://csharpindepth.com/Articles/Singleton) and to adapt a suitable version for your implementation. 83 | For this session, it is not yet necessary that your implementation is thread-safe. 84 | 85 | 86 | ## 3) Ethics 87 | 88 | Now that you test and build your software with GitHub Actions, consider if want to share telemetry data with Microsoft. Per default, Microsoft collects data about many actions that you perform using their tools, see e.g., https://learn.microsoft.com/en-us/dotnet/core/tools/telemetry and https://dotnet.microsoft.com/en-us/platform/telemetry. 89 | 90 | Remember, that you can disable telemetry when using the `dotnet` command by creating an environment variable set to true before invoking any `dotnet` commands: 91 | 92 | * `DOTNET_CLI_TELEMETRY_OPTOUT=1` or 93 | * `DOTNET_CLI_TELEMETRY_OPTOUT=true` 94 | 95 | See the [official documentation](https://docs.github.com/en/actions/learn-github-actions/variables) to see how to define respective environment variables in GitHub Actions workflows. 96 | 97 | 98 | ## 4) Prepare for next session 99 | 100 | Next session, we need that you are signed-up to Microsoft's cloud-service platform, which is called _Azure_. 101 | 102 | - To sign up to Azure with free student credits, follow [this guide](https://app.tango.us/app/workflow/Steps-to-Sign-Up-for-Azure-with-Student-Mail-285020aa8d76412eada4b6915b695de2) 103 | - Note, follow mainly what is illustrated on the image. Except of the first link, you will just navigate through the illustrated flow of actions. 104 | - OBS: of course fill in your name, birthday, email address, etc. 105 | - Thereafter, [install the Azure CLI client](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) before class. 106 | - Make sure that you can login and out to Azure from the command-line via `az login` and `az logout` respectively. 107 | * Verify that you can log onto with your ITU credentials. 108 | -------------------------------------------------------------------------------- /sessions/session_03/images/SE_TDD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_03/images/SE_TDD.png -------------------------------------------------------------------------------- /sessions/session_03/images/instable_component.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_03/images/instable_component.png -------------------------------------------------------------------------------- /sessions/session_03/images/stable_component.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_03/images/stable_component.png -------------------------------------------------------------------------------- /sessions/session_04/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_04/.gitkeep -------------------------------------------------------------------------------- /sessions/session_04/AsyncAwaitHTTP/.idea/.idea.AsyncAwaitHTTP.dir/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Rider ignored files 5 | /contentModel.xml 6 | /projectSettingsUpdater.xml 7 | /.idea.AsyncAwaitHTTP.iml 8 | /modules.xml 9 | # Editor-based HTTP Client requests 10 | /httpRequests/ 11 | # Datasource local storage ignored files 12 | /dataSources/ 13 | /dataSources.local.xml 14 | -------------------------------------------------------------------------------- /sessions/session_04/AsyncAwaitHTTP/.idea/.idea.AsyncAwaitHTTP.dir/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /sessions/session_04/AsyncAwaitHTTP/.idea/.idea.AsyncAwaitHTTP.dir/.idea/indexLayout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sessions/session_04/AsyncAwaitHTTP/.idea/.idea.AsyncAwaitHTTP.dir/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /sessions/session_04/AsyncAwaitHTTP/src/Client/Client.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net7.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /sessions/session_04/AsyncAwaitHTTP/src/Client/Program.cs: -------------------------------------------------------------------------------- 1 | // Create an HTTP client object 2 | var baseURL = "http://localhost:5088"; 3 | using HttpClient client = new(); 4 | client.BaseAddress = new Uri(baseURL); 5 | 6 | // Sequential execution 7 | var watch = System.Diagnostics.Stopwatch.StartNew(); 8 | // first HTTP request 9 | var fstResponse = await client.GetAsync("/"); 10 | Console.WriteLine((fstResponse)); 11 | // second HTTP request 12 | var sndResponse = await client.GetAsync("/"); 13 | watch.Stop(); 14 | 15 | Console.WriteLine($"Sequential HTTP requests ... done after {watch.ElapsedMilliseconds}ms"); 16 | 17 | // Concurrent execution 18 | watch = System.Diagnostics.Stopwatch.StartNew(); 19 | // first HTTP request 20 | var fstRequestTask = client.GetAsync("/"); 21 | // second HTTP request 22 | var sndRequestTask = client.GetAsync("/"); 23 | 24 | var thrdResponse = await fstRequestTask; 25 | var frthResponse = await sndRequestTask; 26 | watch.Stop(); 27 | 28 | Console.WriteLine($"Concurrent HTTP requests ... done after {watch.ElapsedMilliseconds}ms"); 29 | -------------------------------------------------------------------------------- /sessions/session_04/AsyncAwaitHTTP/src/Server/Program.cs: -------------------------------------------------------------------------------- 1 | var builder = WebApplication.CreateBuilder(args); 2 | var app = builder.Build(); 3 | 4 | app.MapGet("/", () => 5 | { 6 | Thread.Sleep(2000); 7 | return "Hello World!"; 8 | }); 9 | 10 | app.Run(); 11 | -------------------------------------------------------------------------------- /sessions/session_04/AsyncAwaitHTTP/src/Server/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:52790", 7 | "sslPort": 44357 8 | } 9 | }, 10 | "profiles": { 11 | "http": { 12 | "commandName": "Project", 13 | "dotnetRunMessages": true, 14 | "launchBrowser": true, 15 | "applicationUrl": "http://localhost:5088", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "https": { 21 | "commandName": "Project", 22 | "dotnetRunMessages": true, 23 | "launchBrowser": true, 24 | "applicationUrl": "https://localhost:7088;http://localhost:5088", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | }, 29 | "IIS Express": { 30 | "commandName": "IISExpress", 31 | "launchBrowser": true, 32 | "environmentVariables": { 33 | "ASPNETCORE_ENVIRONMENT": "Development" 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /sessions/session_04/AsyncAwaitHTTP/src/Server/Server.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /sessions/session_04/AsyncAwaitHTTP/src/Server/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /sessions/session_04/AsyncAwaitHTTP/src/Server/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /sessions/session_04/READING_MATERIAL.md: -------------------------------------------------------------------------------- 1 | # Reading Material for Session 04 2 | 3 | * For preparation: [install the Azure CLI client](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) 4 | * Read chapters three, four, and five from [Andrew Lock _ASP.NET Core in Action, Third Edition_](https://www.manning.com/books/asp-net-core-in-action-third-edition) 5 | 6 | 7 | ## HTTP Messages 8 | 9 | * [Description of HTTP Messages](https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages) 10 | 11 | 12 | ## C♯ 13 | 14 | * [Lambda expressions and anonymous functions](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/lambda-expressions) 15 | * [Intro to C♯'s `await` operator](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/await) 16 | * [Introduction to asynchronous programming with `async` and `await` in C♯](https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/) 17 | * Optional: A quite long but elaborate and historical explaination of [How Async/Await Really Works in C♯](https://devblogs.microsoft.com/dotnet/how-async-await-really-works/) 18 | 19 | ## (ASP).NET Core 20 | 21 | * [Minimal Web APIs](https://learn.microsoft.com/en-us/aspnet/core/tutorials/min-web-api?view=aspnetcore-7.0&tabs=visual-studio-code) 22 | * [Tutorial: Make HTTP requests in a .NET console app using C♯](https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/console-webapiclient) 23 | * [Make HTTP requests with the `HttpClient` class](https://learn.microsoft.com/en-us/dotnet/fundamentals/networking/http/httpclient) 24 | * [Official documentation of `HttpClient` Class](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=net-7.0) 25 | * [ASP.NET Core Middleware](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-7.0) 26 | * [How to serialize and deserialize (marshal and unmarshal) JSON in .NET](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/how-to?pivots=dotnet-7-0) 27 | 28 | 29 | ## Patterns 30 | 31 | * [Builder pattern introduction](https://refactoring.guru/design-patterns/builder) 32 | * A [builder pattern example in Java](https://www.digitalocean.com/community/tutorials/builder-design-pattern-in-java) 33 | 34 | 35 | ## UML Diagram Notation 36 | 37 | * [UML Sequence Diagrams](https://www.uml-diagrams.org/sequence-diagrams.html) 38 | * [UML Component Diagrams](https://www.uml-diagrams.org/component-diagrams.html) 39 | * [UML Deployment Diagrams](https://www.uml-diagrams.org/deployment-diagrams-overview.html) 40 | 41 | 42 | ## GitHub Actions for Deployment to Azure App Services 43 | 44 | In case you want to read more detailed documentation on how to manually configure and setup a GitHub Actions workflow for deployment to Azure App Service, read the following official documentation documents from Microsoft and GitHub: 45 | 46 | * https://learn.microsoft.com/en-us/azure/app-service/deploy-github-actions 47 | * https://learn.microsoft.com/en-us/dotnet/architecture/devops-for-aspnet-developers/actions-deploy 48 | * https://docs.github.com/en/actions/deployment/deploying-to-your-cloud-provider/deploying-to-azure/deploying-net-to-azure-app-service 49 | -------------------------------------------------------------------------------- /sessions/session_04/README_PROJECT.md: -------------------------------------------------------------------------------- 1 | # Your turn now! — Project Work 2 | 3 | 4 | 5 | You have to work on the following topics. 6 | 7 | - [1) Software Development](#1-software-development) 8 | - [2) Process](#2-process) 9 | - [3) Project Review 1](#3-project-review-1) 10 | - [4) Prepare for next session](#4-prepare-for-next-session) 11 | 12 | Remember, you have to perform work on each topic and on **each** bullet point. 13 | Be done with the project work before we meet again next Thursday. 14 | 15 | 16 | 17 | ## 1) Software Development 18 | 19 | ### 1.a) Refactor the CSV Database to a Web Service 20 | 21 | Implement two endpoints in your CSV database web service: `/cheep` and `/cheeps`. 22 | Sending a JSON object, e.g., of the form `{"Author":"ropf","Message":"Hello, World!", "Timestamp": 1684229348}` as the body of an HTTP POST request to the `/cheep` endpoint shall store the cheep in the remote database. 23 | An HTTP GET request to the `/cheeps` endpoint shall return all cheeps that are stored in the CSV database as a list of JSON objects. 24 | 25 | This is a refactoring step. 26 | That is, reuse suitable code from your current SimpleDB library project and move its functionality behind the web interface described above. 27 | 28 | 29 | ### 1.b) Refactor your _Chirp!_ CLI client to use the CSV Database Web Service 30 | 31 | Refactor your client application so that it uses the web service CSV database to store and read cheeps. 32 | That is, your _Chirp!_ CLI client shall now send HTTP `GET` and `POST` requests to the `/cheeps` and `/cheep` endpoint respectively. 33 | It shall not call the methods from your `SimpleDB` library project directly anymore. 34 | 35 | Do this refactoring in small steps: 36 | 37 | #### Make both the CSV Database Web Service and the _Chirp!_ CLI client work on `localhost` 38 | 39 | Make sure that the CSV database web service and the refactored _Chirp!_ CLI client work together as intended when both are executed on `localhost`. 40 | 41 | #### Adapt your test suite 42 | 43 | Adapt your unit, integration and end-to-end tests from last week's exercise so that they test the _Chirp!_ application with its new architecture. 44 | 45 | Suitable integration tests for the CSV Database Web Service are likely: 46 | 47 | a) When you send an HTTP `GET` request to the `/cheeps` endpoint the status code of the HTTP response is `200` and the response body contains a list of `Cheep` objects serialized to JSON. 48 | b) When you send an HTTP `POST` request to the `/cheep` endpoint with a request body containing a JSON serialized `Cheep` object, you receive `200` as status code of the HTTP response. 49 | 50 | Depending on your test cases of the CLI client, they will likely change only slightly compared to last week. 51 | But likely all `Read` and `Store` method calls of your `SimpleDB` library are replaced by respective HTTP calls. 52 | 53 | #### Deploy your CSV Database Web Service manually to Azure 54 | 55 | Once you are sure that your CSV Database Web Service and _Chirp!_ CLI client can operate as intended on your local computer, manually deploy the CSV Database Web Service to Azure App Services. Do that as in class via: 56 | 57 | ```bash 58 | az login 59 | az webapp up --sku F1 --name bdsagroupchirpremotedb --os-type Linux --location westeurope --runtime DOTNETCORE:7.0 60 | ``` 61 | 62 | **OBS**: replace `` in the `--name` option above with the number of your group **before** executing the command. 63 | 64 | Manually test if your client works together with the remote database when configured with the respective URL. 65 | That is, your client application has to send requests to the newly deployed web service (under URL `https://bdsagroupchirpremotedb.azurewebsites.net/`), not to a web service running on `localhost`. 66 | Note, that you can retrieve the correct URL from the output of above command. 67 | 68 | Additionally, from now on cheeps are no longer stored in a local CSV file on your computer but on the remote service hosted on Azure App Services. 69 | 70 | |:warning:| **Do not** interfere with the CSV Database Web Services from other groups! That is, do not send cheeps to be stored in another group's database!| 71 | |---------|------------------------------------| 72 | 73 | Once you verified that your client can interact with the CSV Database Web Service, shutdown that service with the following commands. The reason is, that you are configuring automatic deployment in the next task. 74 | 75 | ```bash 76 | az webapp delete 77 | az logout 78 | ``` 79 | 80 | ## 2) Process 81 | 82 | ### 2.a) Add Automatic Deployment of your CSV Database Web Service 83 | 84 | Add automatic deployments of your refactored CSV database to Azure App Services as a GitHub Action. 85 | Likely the easiest way to configure a respective GitHub Actions workflow, is by registering the web service once on Azure App Services in the following way: 86 | An illustrated guide of the following steps is accessible [here](https://app.tango.us/app/workflow/Creating-a-Remote-Azure-Database-for--NET-7--STS--on-Linux-with-Deployment-Center-cd9c4e3977184b7fb2a7e2d239e4d54f): 87 | 88 | * Log onto 89 | * Click the following sequence: top tab `App Services` → `+ Create` → choose `Web App` 90 | * Set `Name` to `bdsagroupchirpremotedb`, where `` has to be replaced with the number of your group. 91 | * Set `Region` to `North Europe` 92 | * Set `Runtime stack` to `.NET 7 (STS)` 93 | * Choose `Operating system` `Linux` 94 | * Choose `Pricing Plan` `Free F1 (Shared infrastructure)` 95 | * In the bottom, click the button `Review + create` 96 | * After checking that all configuration is as expected, click the button `Create` in the bottom 97 | 98 | * After reading a message saying _"`Your deployment is complete`"_, click `Go to resource` 99 | * On the left choose `Deployment Center` 100 | * Under `Source`, select `GitHub` 101 | * Click `Authorize` 102 | * Now choose organization (for you, it is your GitHub organization, i.e., `ITU-BDSA2024-GROUP`), your repository (`Chirp`) and the `main` branch 103 | * Finish by clicking the `Save` button on the top 104 | 105 | The last steps automatically create and store a GitHub Actions workflow in your repository and it automatically configures the required environment variables and secrets on GitHub. 106 | 107 | In case your project is organized into `src` and `test` directories, you have to point the build and publish commands to the right projects in the repository: 108 | - Change lines 25 - 29 to: 109 | ```yaml 110 | - name: Build with dotnet 111 | run: dotnet build src// --configuration Release 112 | 113 | - name: dotnet publish 114 | run: dotnet publish src// -c Release -o ${{env.DOTNET_ROOT}}/myapp 115 | ``` 116 | 117 | After successful execution of the workflow, the app is available under: `https://bdsagroupchirpremotedb.azurewebsites.net/` 118 | 119 | ### 2.b) Continue Automatic Releases of your _Chirp!_ CLI Clients 120 | 121 | Continue to automatically release new versions of the CLI client. That is, now release at least one new version of the _Chirp!_ CLI client that is able to interact with your CSV Database Web Service. 122 | 123 | Note, while all project groups are discouraged to interact with other group's CSV Database Web Services, be prepared for that the teachers or TAs send a small amount of `Cheeps` and want to read a small amount of these too. 124 | 125 | ## 3) Project Review 1 126 | 127 | Prepare for the first project review next week. 128 | Be prepared to demonstrate and inspect with the assigned TA: 129 | * How you build, test, and deploy your projects 130 | * The current state of your project, i.e., local CLI based clients that talk to a web service database or that interact with a local `SimpleDB` CSV database. 131 | 132 | In case you cannot meet with the TA who is assigned to your group, let her know well in advance that you cannot and reschedule to meeting to another suitable time slot! 133 | 134 | ## 4) Prepare for next session 135 | 136 | Next session, we need that you have the `sqlite3` CLI program installed. 137 | Do that on the terminal as described in the following: 138 | 139 | - On WSL and Linux: `sudo apt install sqlite3` 140 | - On MacOS `brew install sqlite3` 141 | -------------------------------------------------------------------------------- /sessions/session_04/images/client_server_comp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_04/images/client_server_comp.png -------------------------------------------------------------------------------- /sessions/session_04/images/client_server_comp_db.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_04/images/client_server_comp_db.png -------------------------------------------------------------------------------- /sessions/session_04/images/client_server_seq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_04/images/client_server_seq.png -------------------------------------------------------------------------------- /sessions/session_04/images/client_server_seq_db.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_04/images/client_server_seq_db.png -------------------------------------------------------------------------------- /sessions/session_04/images/db_schema.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_04/images/db_schema.png -------------------------------------------------------------------------------- /sessions/session_04/images/deployment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_04/images/deployment.png -------------------------------------------------------------------------------- /sessions/session_04/images/inspector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_04/images/inspector.png -------------------------------------------------------------------------------- /sessions/session_04/images/middleware.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_04/images/middleware.png -------------------------------------------------------------------------------- /sessions/session_04/images/multi_clients_server_comp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_04/images/multi_clients_server_comp.png -------------------------------------------------------------------------------- /sessions/session_05/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_05/.gitkeep -------------------------------------------------------------------------------- /sessions/session_05/Chirp.SQLite/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | // Use IntelliSense to find out which attributes exist for C# debugging 6 | // Use hover for the description of the existing attributes 7 | // For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md 8 | "name": ".NET Core Launch (console)", 9 | "type": "coreclr", 10 | "request": "launch", 11 | "preLaunchTask": "build", 12 | // If you have changed target frameworks, make sure to update the program path. 13 | "program": "${workspaceFolder}/bin/Debug/net7.0/Chirp.SQLite.dll", 14 | "args": [], 15 | "cwd": "${workspaceFolder}", 16 | // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console 17 | "console": "internalConsole", 18 | "stopAtEntry": false 19 | }, 20 | { 21 | "name": ".NET Core Attach", 22 | "type": "coreclr", 23 | "request": "attach" 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /sessions/session_05/Chirp.SQLite/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "command": "dotnet", 7 | "type": "process", 8 | "args": [ 9 | "build", 10 | "${workspaceFolder}/Chirp.SQLite.csproj", 11 | "/property:GenerateFullPaths=true", 12 | "/consoleloggerparameters:NoSummary" 13 | ], 14 | "problemMatcher": "$msCompile" 15 | }, 16 | { 17 | "label": "publish", 18 | "command": "dotnet", 19 | "type": "process", 20 | "args": [ 21 | "publish", 22 | "${workspaceFolder}/Chirp.SQLite.csproj", 23 | "/property:GenerateFullPaths=true", 24 | "/consoleloggerparameters:NoSummary" 25 | ], 26 | "problemMatcher": "$msCompile" 27 | }, 28 | { 29 | "label": "watch", 30 | "command": "dotnet", 31 | "type": "process", 32 | "args": [ 33 | "watch", 34 | "run", 35 | "--project", 36 | "${workspaceFolder}/Chirp.SQLite.csproj" 37 | ], 38 | "problemMatcher": "$msCompile" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /sessions/session_05/Chirp.SQLite/Chirp.SQLite.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net$(NETCoreAppMaximumVersion) 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /sessions/session_05/Chirp.SQLite/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | using Microsoft.Data.Sqlite; 3 | 4 | var sqlDBFilePath = "/tmp/chirp.db"; 5 | var sqlQuery = @"SELECT * FROM message ORDER by message.pub_date desc"; 6 | 7 | using (var connection = new SqliteConnection($"Data Source={sqlDBFilePath}")) 8 | { 9 | connection.Open(); 10 | 11 | var command = connection.CreateCommand(); 12 | command.CommandText = sqlQuery; 13 | 14 | using var reader = command.ExecuteReader(); 15 | while (reader.Read()) 16 | { 17 | // https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqldatareader?view=dotnet-plat-ext-7.0#examples 18 | var dataRecord = (IDataRecord)reader; 19 | for (int i = 0; i < dataRecord.FieldCount; i++) 20 | Console.WriteLine($"{dataRecord.GetName(i)}: {dataRecord[i]}"); 21 | 22 | // See https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqldatareader.getvalues?view=dotnet-plat-ext-7.0 23 | // for documentation on how to retrieve complete columns from query results 24 | Object[] values = new Object[reader.FieldCount]; 25 | int fieldCount = reader.GetValues(values); 26 | for (int i = 0; i < fieldCount; i++) 27 | Console.WriteLine($"{reader.GetName(i)}: {values[i]}"); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /sessions/session_05/Chirp.SQLite/data/dump.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO user VALUES(1,'Helge','ropf@itu.dk'); 2 | INSERT INTO user VALUES(2,'Adrian','adho@itu.dk'); 3 | 4 | INSERT INTO message VALUES(1,1,'Hello, BDSA students!',1690892208); 5 | INSERT INTO message VALUES(2,2,'Hej, velkommen til kurset.',1690895308); 6 | -------------------------------------------------------------------------------- /sessions/session_05/Chirp.SQLite/data/schema.sql: -------------------------------------------------------------------------------- 1 | drop table if exists user; 2 | create table user ( 3 | user_id integer primary key autoincrement, 4 | username string not null, 5 | email string not null 6 | ); 7 | 8 | drop table if exists message; 9 | create table message ( 10 | message_id integer primary key autoincrement, 11 | author_id integer not null, 12 | text string not null, 13 | pub_date integer 14 | ); 15 | -------------------------------------------------------------------------------- /sessions/session_05/Chirp.SQLite/scripts/initDB.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | sqlite3 /tmp/chirp.db < data/schema.sql 3 | sqlite3 /tmp/chirp.db < data/dump.sql 4 | -------------------------------------------------------------------------------- /sessions/session_05/DIExample/DIExample.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /sessions/session_05/DIExample/DirectDependency.cs: -------------------------------------------------------------------------------- 1 | namespace DirectDependencyExample; 2 | public class Informer 3 | { 4 | private readonly DIExample.Writer.StdIoWriter _messageWriter = new(); 5 | public void Inform(string message) => _messageWriter.Write(message); 6 | } 7 | -------------------------------------------------------------------------------- /sessions/session_05/DIExample/InjectedDependency.cs: -------------------------------------------------------------------------------- 1 | namespace InjectedDependencyExample; 2 | public class Informer 3 | { 4 | private readonly DIExample.Writer.IWriter _messageWriter; 5 | 6 | public Informer(DIExample.Writer.IWriter messageWriter) => _messageWriter = messageWriter; 7 | 8 | public void Inform(string message) => _messageWriter.Write(message); 9 | } 10 | -------------------------------------------------------------------------------- /sessions/session_05/DIExample/Program.cs: -------------------------------------------------------------------------------- 1 | var builder = WebApplication.CreateBuilder(args); 2 | var app = builder.Build(); 3 | 4 | app.MapGet("/a/{endpoint}", (string endpoint) => 5 | { 6 | var informer = new DirectDependencyExample.Informer(); 7 | informer.Inform(endpoint); 8 | }); 9 | 10 | app.MapGet("/b/{endpoint}", (string endpoint) => 11 | { 12 | var informer = new InjectedDependencyExample.Informer(new DIExample.Writer.StdIoWriter()); 13 | informer.Inform(endpoint); 14 | }); 15 | 16 | app.Run(); 17 | -------------------------------------------------------------------------------- /sessions/session_05/DIExample/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:42770", 7 | "sslPort": 44309 8 | } 9 | }, 10 | "profiles": { 11 | "http": { 12 | "commandName": "Project", 13 | "dotnetRunMessages": true, 14 | "launchBrowser": true, 15 | "applicationUrl": "http://localhost:5163", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "https": { 21 | "commandName": "Project", 22 | "dotnetRunMessages": true, 23 | "launchBrowser": true, 24 | "applicationUrl": "https://localhost:7173;http://localhost:5163", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | }, 29 | "IIS Express": { 30 | "commandName": "IISExpress", 31 | "launchBrowser": true, 32 | "environmentVariables": { 33 | "ASPNETCORE_ENVIRONMENT": "Development" 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /sessions/session_05/DIExample/Writer.cs: -------------------------------------------------------------------------------- 1 | namespace DIExample.Writer; 2 | 3 | public interface IWriter 4 | { 5 | public void Write(string message); 6 | } 7 | 8 | public class StdIoWriter : IWriter 9 | { 10 | public void Write(string message) => Console.WriteLine(message); 11 | } 12 | 13 | public class FileWriter : IWriter 14 | { 15 | public void Write(string message) 16 | { 17 | string docPath = Path.GetTempPath(); 18 | using StreamWriter outputFile = new(Path.Combine(docPath, "store.txt")); 19 | outputFile.WriteLine(message); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sessions/session_05/DIExample/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /sessions/session_05/DIExample/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /sessions/session_05/READING_MATERIAL.md: -------------------------------------------------------------------------------- 1 | # Reading Material for Session 05 2 | 3 | * Read chapters 13, 14, and 15 from [Andrew Lock _ASP.NET Core in Action, Third Edition_](https://www.manning.com/books/asp-net-core-in-action-third-edition) 4 | 5 | 6 | ## ASP.NET 7 | 8 | * [Intro to Razor Page applications](https://learn.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/razor-pages-start?view=aspnetcore-7.0&tabs=visual-studio-code) (only this page is relevant for this week, the following become relevant next week) 9 | * [Use SQLite database](https://learn.microsoft.com/en-us/dotnet/standard/data/sqlite/?tabs=netcore-cli) 10 | 11 | 12 | ## Testing 13 | 14 | * [Integration tests of Razor Page Applications](https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-7.0) 15 | 16 | 17 | ## GitHub 18 | 19 | * [Creating a pull request from one branch to another](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) 20 | * [Requesting a review](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/requesting-a-pull-request-review) 21 | -------------------------------------------------------------------------------- /sessions/session_05/SimpleHTMLServer/Program.cs: -------------------------------------------------------------------------------- 1 | var builder = WebApplication.CreateBuilder(args); 2 | var app = builder.Build(); 3 | 4 | var htmlText = @"

Hello World!

5 | I am an HTML document from the ITU BDSA course. 6 | "; 7 | app.Map("/", () => Results.Content(htmlText, "text/html")); 8 | 9 | app.Run(); 10 | -------------------------------------------------------------------------------- /sessions/session_05/SimpleHTMLServer/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:18780", 7 | "sslPort": 44384 8 | } 9 | }, 10 | "profiles": { 11 | "http": { 12 | "commandName": "Project", 13 | "dotnetRunMessages": true, 14 | "launchBrowser": true, 15 | "applicationUrl": "http://localhost:5181", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "https": { 21 | "commandName": "Project", 22 | "dotnetRunMessages": true, 23 | "launchBrowser": true, 24 | "applicationUrl": "https://localhost:7216;http://localhost:5181", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | }, 29 | "IIS Express": { 30 | "commandName": "IISExpress", 31 | "launchBrowser": true, 32 | "environmentVariables": { 33 | "ASPNETCORE_ENVIRONMENT": "Development" 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /sessions/session_05/SimpleHTMLServer/SimpleHTMLServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net$(NETCoreAppMaximumVersion) 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /sessions/session_05/SimpleHTMLServer/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /sessions/session_05/SimpleHTMLServer/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /sessions/session_05/data/schema.sql: -------------------------------------------------------------------------------- 1 | drop table if exists user; 2 | create table user ( 3 | user_id integer primary key autoincrement, 4 | username string not null, 5 | email string not null, 6 | pw_hash string not null 7 | ); 8 | 9 | drop table if exists message; 10 | create table message ( 11 | message_id integer primary key autoincrement, 12 | author_id integer not null, 13 | text string not null, 14 | pub_date integer 15 | ); 16 | -------------------------------------------------------------------------------- /sessions/session_05/images/accross_pkg_dep.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_05/images/accross_pkg_dep.png -------------------------------------------------------------------------------- /sessions/session_05/images/direct_dep.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_05/images/direct_dep.png -------------------------------------------------------------------------------- /sessions/session_05/images/inversed_dep.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_05/images/inversed_dep.png -------------------------------------------------------------------------------- /sessions/session_05/images/simpledb_deployment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_05/images/simpledb_deployment.png -------------------------------------------------------------------------------- /sessions/session_05/images/sqlite_deployment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_05/images/sqlite_deployment.png -------------------------------------------------------------------------------- /sessions/session_05/images/ssr_sq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_05/images/ssr_sq.png -------------------------------------------------------------------------------- /sessions/session_05/scripts/initDB.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | sqlite3 /tmp/chirp.db < data/schema.sql 3 | sqlite3 /tmp/chirp.db < data/dump.sql 4 | -------------------------------------------------------------------------------- /sessions/session_06/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_06/.gitkeep -------------------------------------------------------------------------------- /sessions/session_06/Feedback.md: -------------------------------------------------------------------------------- 1 | --- 2 | theme: gaia 3 | _class: lead 4 | paginate: true 5 | backgroundColor: #fff 6 | backgroundImage: url('https://marp.app/assets/hero-background.svg') 7 | footer: '![width:300px](https://github.com/itu-bdsa/lecture_notes/blob/main/images/banner.png?raw=true)' 8 | headingDivider: 2 9 | marp: true 10 | style: | 11 | section { 12 | font-size: 25px; 13 | } 14 | container { 15 | height: 300px; 16 | width: 100%; 17 | display: block; 18 | justify-content: right; 19 | text-align: right; 20 | } 21 | header { 22 | float: right; 23 | } 24 | 25 | a { 26 | color: blue; 27 | text-decoration: underline; 28 | background-color: lightgrey; 29 | font-size: 80%; 30 | } 31 | 32 | table { 33 | font-size: 22px; 34 | } 35 | --- 36 | 37 | # **Analysis, Design and Software Architecture (BDSA)** 38 | Session 6 — Feedback 39 | [Helge Pfeiffer](ropf@itu.dk) 40 | 41 | 42 | ## Feedback 43 | 44 | 45 | 46 | All groups are working on their projects. 47 | Super cool! 48 | 49 | 50 | ## Feedback 51 | 52 | 53 | 54 | 55 | ## Read carefully: follow URL specification! 56 | 57 | Timelines of users should appear under the endpoint with the name of the user. 58 | 59 | 60 | > For example, given the [example database dump](./data/dump.sql), a response body for a `GET` request send to `/Helge` shall contain a cheep written by `Helge` and the content of a cheep shall be `Hello, BDSA students!` 61 | > Similarly, a response body for a `GET` request send to `/Adrian` shall contain a cheep written by `Adrian` with the content `Hej, velkommen til kurset.` 62 | > 63 | > [1.c) Add initial testing](../session_05/README_PROJECT.md) 64 | 65 | That is, for example `/Author/Helge` is another endpoint. 66 | 67 | 68 | ## Feedback 69 | 70 | - Have **one** main branch called `main`. 71 | - Remember, we do trunk-based development in this course. That is, you do not have a long-lived `dev` branch (as in last semester's project). That would be another branching strategy. 72 | - You have short-lived feature branches. That is, at latest after a day your changes land on the main branch and thereby automatically in production (your deployment workflows deploy all changes from main, right?) 73 | 74 | What do we do if we cannot finish our feature during a day? 75 | 76 | - Good observation, that means likely that your task descriptions in your issues are too coarse grained. Over time you should train to make them smaller so that you can complete your tasks in max. a day. 77 | 78 | 79 | ## Feedback 80 | 81 | - Have **one** main branch called `main`. 82 | - It is not advisable to have a `main2.0` branch. 83 | - Likely, it is also not a good idea to call a branch `origin` since it is confusing when pointing to remote repositories in git commands. 84 | 85 | 86 | ## Process: Scientific problem solving 87 | 88 | Our software does not work as intended: What to do? 89 | 90 | > 1. Identify the problem 91 | > 2. Gather information 92 | > 3. Iterate potential solutions 93 | > 4. Test your solution 94 | Source: E. Cain 4 steps to solving any software problem 95 | 96 | 97 | 98 | ## Azure App Service: Reading the Logs 99 | 100 | One way to identify the problem for depolyed web-applications: read the logs 101 | 102 | ![w:1000px](images/azure_logs.png) 103 | 104 | 105 | ## Data Transfer Objects, what are these? 106 | 107 | > A Data Transfer Object is an object that is used to encapsulate data, and send it from one subsystem of an application to another. 108 | > 109 | > DTOs are most commonly used by the Services layer in an N-Tier application to transfer data between itself and the UI layer. 110 | > 111 | > [StackOverflow Question](https://stackoverflow.com/questions/1051182/what-is-a-data-transfer-object-dto) 112 | 113 | 114 | ## Data Transfer Objects (DTOs)? 115 | 116 | > Right now, our web API exposes the database entities to the client. The client receives data that maps directly to your database tables. However, that's not always a good idea. Sometimes you want to change the shape of the data that you send to client. For example, you might want to: 117 | > 118 | > - Remove circular references [...]. 119 | > - Hide particular properties that clients are not supposed to view. 120 | > - Omit some properties in order to reduce payload size. 121 | > - Flatten object graphs that contain nested objects, to make them more convenient for clients. 122 | > - Avoid "over-posting" vulnerabilities. [...] 123 | > - Decouple your service layer from your database layer. 124 | > 125 | > [Microsoft Documentation](https://learn.microsoft.com/en-us/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-5) 126 | 127 | 128 | ## Next Week: Guest Lecture 129 | 130 | ![bg right](https://www.twobirds.com/-/media/twobirdssite/people/lawyers/photos/denmark/martin-vonhaller/martin-vonhaller-mobile.jpg?h=435&iar=0&w=750&hash=2F2B45E76908434DCF00E39834D8F4C2) 131 | 132 | [Martin von Haller Grønbæk](https://www.twobirds.com/en/people/m/martin-von-haller-groenbaek), one of Denmark's leading IT lawyers, will give a guest lecture on _Software Licenses and Software License Compatibility_. 133 | 134 | The lecture will start at 11:00 (sharp) in Auditorium 1. So be there on time, best 10:50. 135 | After his guest lecture, Martin will be available for deeper questions and discussions in the canteen (12:00 - 12:30). 136 | -------------------------------------------------------------------------------- /sessions/session_06/READING_MATERIAL.md: -------------------------------------------------------------------------------- 1 | # Reading Material for Session 06 2 | 3 | * Read chapter 12 from [Andrew Lock _ASP.NET Core in Action, Third Edition_](https://www.manning.com/books/asp-net-core-in-action-third-edition) 4 | 5 | ## ASP.NET Core 6 | 7 | * [Intro to Razor Page applications](https://learn.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/razor-pages-start?view=aspnetcore-7.0&tabs=visual-studio-code) 8 | * [Getting Started with EF Core](https://learn.microsoft.com/en-us/ef/core/get-started/overview/first-app?tabs=netcore-cli) 9 | * [EF Core with Razor Pages](https://learn.microsoft.com/en-us/aspnet/core/data/ef-rp/intro?view=aspnetcore-7.0&tabs=visual-studio) 10 | * [Repository pattern](https://learn.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-design) 11 | * On Data Transfer Objects: 12 | - [A blog post explaining DTO's in ASP.Net Razor Pages](https://www.nilebits.com/blog/2024/02/aspnet-mvc-data-transfer-objects/) 13 | - [DTOs in a WebAPI example](https://learn.microsoft.com/en-us/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-5) 14 | - [What is a DTO?](https://stackoverflow.com/questions/1051182/what-is-a-data-transfer-object-dto) 15 | -------------------------------------------------------------------------------- /sessions/session_06/README_PROJECT.md: -------------------------------------------------------------------------------- 1 | # Your turn now! -- Project Work 2 | 3 | 4 | 5 | You have to work on the following topics. 6 | 7 | - [1) Software Development](#1-software-development) 8 | - [2) Process](#2-process) 9 | 10 | Remember, you have to perform work on each topic and on **each** bullet point. 11 | Be done with the project work before we meet again next week. 12 | 13 | 14 | ## 1) Software Development 15 | 16 | Refactor `Chirp.Razor` away from direct SQLite access to EF Core 17 | 18 | After this session, we realized that our direct dependence on SQLite and its dialect of SQL is less optimal. 19 | Consequently, refactor your `Chirp.Razor` application to use EF Core instead of SQLite directly. 20 | However, continue to use SQLite as your underlying database. 21 | 22 | The functionality of your `Chirp.Razor` application will not be different compared to last week. 23 | That is, you have an application that can display public and private timelines, both of which are paginated to 32 cheeps per page. 24 | 25 | ### 1.a) Data Model 26 | 27 | Create a data model for your `Chirp.Razor` application. 28 | In the end, your data model shall consist of two classes: `Cheep` and `Author`. 29 | For now, an author has a `Name` and an `Email` address (both of which are strings). 30 | A `Cheep` contains a `Text` and a `TimeStamp`, where the former is a string and the latter is a `DateTime`. 31 | Additionally, each `Cheep` refers to its `Author` and each `Author` keeps a reference to all its `Cheeps`. 32 | 33 | Note, we intend you to implement this data model by hand as two classes as in the in-class task. 34 | That is, we do not want you to convert last week's SQL schema into a data model via automatic tooling. 35 | 36 | ### 1.b) Repository Pattern 37 | 38 | Implement the _Repository_ pattern in your application. 39 | Likely, you will create a `CheepRepository`, which gathers information about the cheeps that your application displays in timelines. 40 | Configure the ASP.NET DI container (dependency injection container) so that instances of `CheepRepository` are injected into your application wherever needed. 41 | That is, none of your views, services, etc. has a direct dependency onto `CheepRepository`. 42 | 43 | ### 1.c) Data Transfer Objects (DTOs) 44 | 45 | The information that your application receives from the `CheepRepository` is more rich than what your application needs to display to users. 46 | Consequently, create DTOs that transport information to your views. 47 | Usually, it is advisable that DTOs consist of fields of predefined types only, i.e., `int`, `strings`, etc. `DateTime` is not a predefined type. 48 | 49 | ### 1.d) Seeding the database with example data. 50 | 51 | Use the file [`DbInitializer.cs`](./data/DbInitializer.cs) to import example data into you `Chirp.Razor` application on application start. 52 | 53 | This file becomes part of your project. 54 | That is, your deployed `Chirp.Razor` application on Azure App Services is always seeded with at least this information. 55 | Whenever we access your applications, we expect to find at least the cheeps written by the authors in that file. 56 | 57 | Right after creating your database context object, which we assume to be called `ChirpDBContext`, you can call the only method from `DbInitializer.cs` to seed the example data into your application. 58 | 59 | 60 | ## 2) Process 61 | 62 | ### 2.a) Scientific problem solving 63 | 64 | Do not start programming directly. 65 | Instead, follow the advice from the lecture and start by identification of the problem at hand, i.e., what is the task to be solved, what is the issue, etc. 66 | Now that you identified a problem, do not start programming yet. 67 | Instead, gather information. 68 | For all tasks, it is likely advisable to check the lecture notes, the reading material, and in particular the book for relevant information. 69 | All these sources contain building blocks for your solution. 70 | First now, implement a potential solution that addresses the task at hand. 71 | Evaluate via manual and automated tests if the solution you implemented suitably solves the problem, task, etc. 72 | If not, iterate over this cycle, i.e., problem identification, information gathering, implementation of potential solutions, testing of solutions. 73 | 74 | ### 2.b) Continuous Deployment 75 | 76 | Continue to release and deploy automatically. 77 | That is, during the next weeks, you bring **multiple** new versions `Chirp.Razor` into production, i.e., you deploy them automatically to Azure App Service. 78 | The latest version of the application in production is always the latest version of the application in your main branch. 79 | You decide if it is the latest tagged version or the latest committed version, i.e., if your workflow is triggered by pushes to main or pushes of tags. 80 | 81 | Likely, you have a respective GitHub Actions workflow already from last week. 82 | If not, this task is here to signal that it is high time creating a working deployment workflow. 83 | -------------------------------------------------------------------------------- /sessions/session_06/images/.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_06/images/.png -------------------------------------------------------------------------------- /sessions/session_06/images/EF-Core.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_06/images/EF-Core.png -------------------------------------------------------------------------------- /sessions/session_06/images/ORM-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_06/images/ORM-overview.png -------------------------------------------------------------------------------- /sessions/session_06/images/Repository.svg: -------------------------------------------------------------------------------- 1 | Chat.RepositoryIMessageRepositoryCreateMessage(newMessage : MessageDTO) : TaskReadMessages(userName : string) : Task<List<MessageDTO>>UpdateMessage(alteredMessage : MessageDTO) : TaskMessageRepository... -------------------------------------------------------------------------------- /sessions/session_06/images/azure_logs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_06/images/azure_logs.png -------------------------------------------------------------------------------- /sessions/session_06/images/banner-transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_06/images/banner-transparent.png -------------------------------------------------------------------------------- /sessions/session_06/images/commit_freqs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_06/images/commit_freqs.png -------------------------------------------------------------------------------- /sessions/session_06/images/domain_model.svg: -------------------------------------------------------------------------------- 1 | UserUserId: intName: stringMessages: ICollection<Message>MessageMessageId: intUserId: intText: stringUser: User0..*1 -------------------------------------------------------------------------------- /sessions/session_06/images/repository-pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_06/images/repository-pattern.png -------------------------------------------------------------------------------- /sessions/session_06/images/unit-of-work.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_06/images/unit-of-work.png -------------------------------------------------------------------------------- /sessions/session_07/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_07/.gitkeep -------------------------------------------------------------------------------- /sessions/session_07/READING_MATERIAL.md: -------------------------------------------------------------------------------- 1 | # Reading Material for Session 07 2 | 3 | * Read chapters 8, 9, 10, 12, 35, and 36 from [Andrew Lock _ASP.NET Core in Action, Third Edition_](https://www.manning.com/books/asp-net-core-in-action-third-edition) 4 | 5 | 6 | ## EF Core 7 | 8 | - [Creating and Configuring a Model in EF Core](https://learn.microsoft.com/en-us/ef/core/modeling/) 9 | - [Use data annotations to configure a model](https://learn.microsoft.com/en-us/ef/core/modeling/#use-data-annotations-to-configure-a-model) 10 | - [Indexes and constraints](https://learn.microsoft.com/en-us/ef/core/modeling/indexes?tabs=data-annotations) 11 | - [Entity Properties](https://learn.microsoft.com/en-us/ef/core/modeling/entity-properties) 12 | 13 | 14 | ## Architecture 15 | 16 | - [Common web application architectures](https://learn.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/common-web-application-architectures) 17 | - [Clean Architecture](https://github.com/ardalis/CleanArchitecture/) 18 | - [Command–query separation](https://en.wikipedia.org/wiki/Command–query_separation) 19 | - [CQS versus server generated IDs](https://blog.ploeh.dk/2014/08/11/cqs-versus-server-generated-ids/) 20 | - [Command Query Separation when Queries should have side-effects](https://blog.ploeh.dk/2015/10/08/command-query-separation-when-queries-should-have-side-effects/) 21 | - [CQRS](https://www.martinfowler.com/bliki/CQRS.html) 22 | 23 | 24 | ## Razor Page Applications with EF Core 25 | 26 | - [Razor Pages with Entity Framework Core in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/data/ef-rp/intro?view=aspnetcore-7.0&tabs=visual-studio-code) 27 | 28 | 29 | ## Testing 30 | 31 | * Testing of ASP Chapters 35 and 36 from [Andrew Lock _ASP.NET Core in Action, Third Edition_](https://www.manning.com/books/asp-net-core-in-action-third-edition) 32 | * [Unit testing of ASP.NET Core Razor Pages Applications](https://learn.microsoft.com/en-us/aspnet/core/test/razor-pages-tests?view=aspnetcore-7.0) 33 | * [Testing with in-memory database](https://learn.microsoft.com/en-us/ef/core/testing/testing-without-the-database) 34 | * [Integration tests of Razor Page Applications](https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-7.0) 35 | * [Alternative to testing with in-memory SQLite database](https://learn.microsoft.com/en-us/ef/core/testing/choosing-a-testing-strategy) 36 | 37 | 38 | ## Choosing a Software License 39 | 40 | * [Overview of some potential software licenses](https://choosealicense.com/appendix/) 41 | * [How to add a license to a GitHub project](https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/adding-a-license-to-a-repository) 42 | * [Overview of license compatibility](https://en.wikipedia.org/w/index.php?title=License_compatibility§ion=3#Compatibility_of_FOSS_licenses) 43 | -------------------------------------------------------------------------------- /sessions/session_07/README_PROJECT.md: -------------------------------------------------------------------------------- 1 | # Your turn now! -- Project Work 2 | 3 | 4 | 5 | You have to work on the following topics. 6 | 7 | - [1) Software Development](#1-software-development) 8 | - [2) Process](#2-process) 9 | - [3) Project Review 2](#3-project-review-2) 10 | 11 | 12 | Remember, you have to perform work on each topic and on **each** bullet point. 13 | Be done with the project work before we meet again next week. 14 | 15 | 16 | ## 1) Software Development 17 | 18 | **Note**: You may want to perform these steps in a different order - or simultaneously for some. 19 | 20 | ### 1.a) Use In-memory SQLite Database for Testing 21 | 22 | As we realized during the last weeks, a direct dependency to a certain database is not advisable when running test suites. 23 | 24 | Consequently, configure your integration test suite so that it uses an in-memory SQLite database for testing. 25 | 26 | ### 1.b) Extend Your Repositories 27 | 28 | Expose methods in your repositories (OBS: that includes the respective interfaces) that enable to: 29 | 30 | - Find `Author` by `name` 31 | - Find `Author` by `email` 32 | - Create a new `Author` 33 | 34 | - If not implemented already, retrieve `cheeps` for a certain page. 35 | - If not implemented already, retrieve `cheeps` for a certain page that are written by a certain `Author` who is identified by `name` 36 | - Create a new `cheep`. Note, that might mean to also create a respective author if she does not exist yet in _Chirp!_. 37 | 38 | ### 1.c) Constrain Length of Cheeps 39 | 40 | Constrain cheeps so that only cheeps of length 160 characters are considered valid. 41 | Your _Chirp!_ application should not accept cheeps that are longer than 160 character. 42 | Such cheeps should never be stored to the database. 43 | 44 | Using the mechanisms presented by Adrian, ensure that only `cheep`s up to 160 characters length can be stored. 45 | 46 | ### 1.d) Add Unit Tests 47 | 48 | Now, that you have decoupled your data persistence code properly from your application, augment your test suite from last time. 49 | 50 | Implement a set of unit tests for suitable functionality, e.g., all of the repository methods from the task above, data conversion, etc. 51 | 52 | ### 1.e) Command Query Separation 53 | 54 | Ensure that the methods that are exposed in your repositories follow are separated into commands and queries: 55 | 56 | > Separate Commands from Queries. Commands are procedures that have side effects. Queries are functions that return data. Every method should be either a Command or a Query, but not both. 57 | Source: Mark Seemann "Code That Fits in Your Head" 58 | 59 | 60 | ### 1.f) Onion Architecture 61 | 62 | Refactor your projects into an onion architecture, as seen in class. 63 | That is, in your `src` directory, create a `Chirp.Core` project that contains your DTOs, Repository interface(s), etc., a `Chirp.Infrastucture` project that contains you Repositorie(s), data model, database context, etc., and a `Chirp.Web` project that contains the actual Razor Page application 64 | 65 | ### 1.g) Warnings 66 | 67 | Ensure that your project builds without any warnings. 68 | That is, make sure that *all* warnings in your code are addressed. 69 | 70 | 71 | ## 2) Process 72 | 73 | ### 2.a) Choose a license for your _Chirp!_ project. 74 | 75 | Choose a license for your _Chirp!_ project. 76 | If in doubt about which license might be suitable for your project, consult [choosealicense.com](https://choosealicense.com/) 77 | 78 | Make sure that you can choose the license you want to choose with the dependencies that you declare in your `.csproj` file. 79 | For license compatibility, consider the overview from a [corresponding Wikipedia article](https://en.wikipedia.org/w/index.php?title=License_compatibility§ion=3#Compatibility_of_FOSS_licenses): 80 | 81 | ![](https://upload.wikimedia.org/wikipedia/commons/thumb/2/2b/Floss-license-slide-image.svg/2880px-Floss-license-slide-image.svg.png) 82 | 83 | Place the license text in a file `LICENSE.md`, which you place in the root directory of your project on the main branch. 84 | See [GitHub's documentation](https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/adding-a-license-to-a-repository) on how to add a license to an existing project. 85 | 86 | ### 2.b) Continue to Release 87 | 88 | Continue to release and deploy automatically. 89 | That is, whenever you deploy automatically, you also create a new release. 90 | Meaning, the latest version of the application in production is always the latest version of the application in your main branch. 91 | You decide if it is the latest tagged version or the latest committed version, i.e., if your workflow is triggered by pushes to main or pushes of tags. 92 | 93 | This task is not asking for any new functionality. 94 | Just for that you continue to release automatically as during the last weeks. 95 | 96 | 97 | ## 3) Project Review 2 98 | 99 | Prepare for the second project review (week 43, the week after fall break). 100 | Be prepared to demonstrate and inspect with the assigned TA: 101 | * How you build, test, and deploy your projects 102 | * The current state of your project 103 | 104 | In case you cannot meet with the TA who is assigned to your group, let him know well in advance that you cannot and reschedule to meeting to another suitable time slot! 105 | -------------------------------------------------------------------------------- /sessions/session_07/images/banner-transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_07/images/banner-transparent.png -------------------------------------------------------------------------------- /sessions/session_07/images/domain_model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_07/images/domain_model.png -------------------------------------------------------------------------------- /sessions/session_07/images/domain_model_constrained.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_07/images/domain_model_constrained.png -------------------------------------------------------------------------------- /sessions/session_07/images/entity-framework-core.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_07/images/entity-framework-core.jpg -------------------------------------------------------------------------------- /sessions/session_07/images/fake-provider-and-repository-pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_07/images/fake-provider-and-repository-pattern.png -------------------------------------------------------------------------------- /sessions/session_07/images/onion_architecture.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_07/images/onion_architecture.webp -------------------------------------------------------------------------------- /sessions/session_07/images/unit-of-work-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_07/images/unit-of-work-diagram.png -------------------------------------------------------------------------------- /sessions/session_08/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itu-bdsa/lecture_notes/8da343595474ad728f2f8d64375c1f2a7d5e3843/sessions/session_08/.gitkeep -------------------------------------------------------------------------------- /sessions/session_08/READING_MATERIAL.md: -------------------------------------------------------------------------------- 1 | # Reading Material for Session 08 2 | 3 | * Read chapters 23, 6, and 7 from [Andrew Lock _ASP.NET Core in Action, Third Edition_](https://www.manning.com/books/asp-net-core-in-action-third-edition) 4 | 5 | 6 | ## Introduction to OAuth 7 | 8 | * Read this [blog post](https://developer.okta.com/blog/2019/10/21/illustrated-guide-to-oauth-and-oidc) that describes how OAuth works. 9 | - Alternatively watch [this video](https://youtu.be/t18YB3xDfXI) that accompanyings the article. 10 |
11 | 19 |
20 | 21 | 22 | ## ASP.NET Core Identity and Authentication with Azure App Service 23 | 24 | * [Choose an identity management solution](https://learn.microsoft.com/en-us/aspnet/core/security/how-to-choose-identity-solution) 25 | 26 | * Tutorial [Introduction to Identity on ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity) 27 | 28 | * [Microsoft Entra ID with ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/security/authentication/azure-active-directory/) 29 | 30 | * [Authentication and authorization in Azure App Service and Azure Functions](https://learn.microsoft.com/en-us/azure/app-service/overview-authentication-authorization) 31 | 32 | * [Configure your App Service or Azure Functions app to use GitHub login](https://learn.microsoft.com/en-us/azure/app-service/configure-authentication-provider-github) 33 | 34 | * [Handling of User Secrets](https://learn.microsoft.com/en-gb/aspnet/core/security/app-secrets) 35 | -------------------------------------------------------------------------------- /sessions/session_08/README_PROJECT.md: -------------------------------------------------------------------------------- 1 | # Your turn now! -- Project Work 2 | 3 | 4 | 5 | You have to work on the following topics. 6 | 7 | - [1) Software Development](#1-software-development) 8 | - [2) Process](#2-process) 9 | 10 | 11 | Remember, you have to perform work on each topic and on **each** bullet point. 12 | Be done with the project work before we meet again next week. 13 | 14 | 15 | ## 1) Software Development 16 | 17 | 18 | Add login functionality to your _Chirp!_ applications. 19 | You can do this in many ways and you decide how to do it. 20 | The following two sections (1.a) and 1.b)) discuss possible solutions. 21 | You choose which one you want to implement. 22 | 23 | In any of the cases, we want to have a navigation bar directly below the headline of every page in the _Chirp!_ `

Icon1Chirp!

` 24 | and on top of the list of cheeps that looks similar to the following. 25 | 26 | ![](images/chirp_before_auth.png) 27 | 28 | ![](images/chirp_after_auth.png) 29 | 30 | Such a navigation bar may be implemented in a Razor View via code similar to the following. 31 | 32 | ```html 33 | 51 | ``` 52 | 53 | In the CSS file that you have in your _Chirp!_ projects, there is a style for a navigation element, which you should use, e.g., `