diff --git a/ProjectOrientedSessions/Session04/Session04 Additional Info.md b/ProjectOrientedSessions/Session04/Session04 Additional Info.md index 651c561..eda4497 100644 --- a/ProjectOrientedSessions/Session04/Session04 Additional Info.md +++ b/ProjectOrientedSessions/Session04/Session04 Additional Info.md @@ -1,34 +1,24 @@ -### 1. **Should I have an `IEntityService` and then `EntityService` for each of my entities?** +## *Should I have an `IEntityService` and then `EntityService` for each of my entities?** Not necessarily **for _every_** entity — only if it **makes sense**. - - The Application Layer should expose **use cases** — not just CRUD logic for each entity. - - If an entity has business logic or interactions that need orchestration (e.g., validations, aggregations, calling repositories, etc.), then **yes**, create a service. - - Otherwise, for basic operations, **directly using a repository (via a unit of work or interface)** from the use case handler might be fine. -### 2. **Is it OK to have services not related to a specific entity?** +## **Is it OK to have services not related to a specific entity?** Absolutely, **yes**. In fact, that’s expected in a Clean Architecture setup. Examples: - - A `ReportGenerationService` that combines bookings, customers, and payments. - - A `TokenService` for authentication tokens. - - A `CurrencyConversionService` that hits an external API. - - A `NotificationService` that sends emails or SMS. - 👉 As long as these services **live in the Application Layer** and follow **dependency inversion** (i.e., they depend only on interfaces, not implementations), you’re doing great. -### 3. **Is it necessary to have an interface for each service?** +## **Is it necessary to have an interface for each service?** - - -### 🔹 **What’s the Difference Between Services and Repositories?** +## **What’s the Difference Between Services and Repositories?** | Aspect | **Service** | **Repository** | | ------------------ | ---------------------------------------------------------------------- | --------------------------------------------------------------- | @@ -37,7 +27,7 @@ Examples: | **Focus** | Coordinates multiple domain/repo operations, validation, business flow | Fetching/storing data for a specific entity | | **Example** | `PlaceOrderService`, `ReportService` | `ICustomerRepository`, `IOrderRepository` | -### What does `init` mean? +## What does `init` mean? `init` is an **access modifier for properties** that allows you to **set a property only during object initialization**, **but not after**. @@ -62,21 +52,15 @@ Examples: ### But when should you prefer `class`? Use `class` if your DTO or model: - - Needs to be **mutable** after creation - - Has to **interact with legacy APIs/libraries** - - Needs **inheritance or polymorphism** (not well supported in `record`) - - Has **rich behavior** (logic, methods, validation, etc.) - > For example, in the Domain Layer (Entities, ValueObjects), you'll usually stick to **`class`** — because that's where behavior lives. ## RESTful APIs: -https://aws.amazon.com/what-is/restful-api/#:~:text=RESTful%20API%20is%20an%20interface,applications%20to%20perform%20various%20tasks. - +[read more](https://aws.amazon.com/what-is/restful-api/#:~:text=RESTful%20API%20is%20an%20interface,applications%20to%20perform%20various%20tasks.) ## What Conditions Make an API RESTful? ### Key Principles of REST: @@ -140,22 +124,15 @@ public class CustomerController : ControllerBase { ## List-like stuff in `C#` -Absolutely, let’s go over the main “list-like” data types in C#. They all serve similar purposes—holding multiple items—but differ in functionality, performance, and use cases. Here’s a detailed breakdown: +They all serve similar purposes—holding multiple items—but differ in functionality, performance, and use cases. Here’s a detailed breakdown: 🔷 1. `IEnumerable` - - Namespace: System.Collections.Generic - - Most basic "list-like" abstraction. - - Read-only (forward-only iteration). - - You can use foreach on it. - - Doesn’t support indexing (no .Count, no [i]). - - Often used as the return type to expose a stream of data without giving full collection control. - Example: @@ -166,42 +143,28 @@ foreach (var num in numbers) ``` 💡 Ideal when: - - You want to return a sequence without exposing modification. - - You’re using LINQ chains. - - You’re returning data from a database query. - --- 🔷 2. ICollection - - Extends IEnumerable. - - Adds Count and Add/Remove/Clear methods. - - Still abstract—List and HashSet implement it. - 💡 Useful when: - - You want to expose a collection that can be modified (e.g. Add or Remove). - - You care about the Count. --- -🔷 3. IList - -- Extends ICollection and IEnumerable. - -- Adds index access: list[0] etc. - +🔷 3. `IList` +- Extends `ICollection` and `IEnumerable`. +- Adds index access: `list[0]` etc. - Think of it like a mutable array with dynamic size. - 💡 Use when: @@ -215,15 +178,10 @@ foreach (var num in numbers) 🔷 4. List - A concrete class (not interface). - -- Implements IList, ICollection, IEnumerable. - +- Implements `IList`, `ICollection`, `IEnumerable`. - Backed by an array (auto-resizes). - - Fast read and write. - -- Supports Add, Remove, Insert, IndexOf, etc. - +- Supports `Add`, `Remove`, `Insert`, `IndexOf`, etc. Example: @@ -238,32 +196,23 @@ var second = list[1]; // "Two" --- -🔷 5. IReadOnlyCollection & IReadOnlyList +🔷 5. `IReadOnlyCollection` & `IReadOnlyList` -- IReadOnlyCollection: Just Count and IEnumerable. - -- IReadOnlyList: Adds indexing without modification. - +- `IReadOnlyCollection`: Just Count and `IEnumerable`. +- `IReadOnlyList`: Adds indexing without modification. - Used to expose lists safely (read-only). - 💡 Used when: - - You want to return a list, but prevent any changes. - --- -🔷 6. Array (T[]) +🔷 6. `Array(T[])` - Fixed-size. - - Fastest for indexing. - - Cannot change size. - -- Implements IList (via Array). - +- Implements `IList` (via Array). Example: @@ -276,27 +225,20 @@ numbers[0] = 42; --- -🔷 7. ObservableCollection +🔷 7. `ObservableCollection` -- For WPF/Blazor/WinForms data-binding. - +- For WPF/`Blazor`/WinForms data-binding. - Notifies UI when items are added/removed. - - Implements IList. - 💡 Use in UI apps when the view needs to react to collection changes. --- 🔷 8. HashSet - - Unordered, no duplicates. - -- Implements ICollection, not IList. - +- Implements `ICollection`, not `IList`. - No index access. - 💡 Best for fast membership checking (contains x). @@ -315,6 +257,3 @@ numbers[0] = 42; |ObservableCollection|✔️|✔️|✔️|✔️|UI binding for collections| |HashSet|❌|✔️|❌|❌|Fast lookup, uniqueness enforcement| -— - -If you tell me the scenario (e.g. search results, modifying a cart, populating a drop-down), I can recommend the best type for it. Want that? diff --git a/ProjectOrientedSessions/Session04/Session04 Backend.md b/ProjectOrientedSessions/Session04/Session04 Backend.md index f5e5bcb..bb9021f 100644 --- a/ProjectOrientedSessions/Session04/Session04 Backend.md +++ b/ProjectOrientedSessions/Session04/Session04 Backend.md @@ -1,19 +1,20 @@ -# Preparation: + + +# 🛠️ Task Checklist + +## Preparation: The unedited conversation with Chat GPT, concerning almost all of the aspects of this session: (optional): read this to get a better understanding of the topic: https://chatgpt.com/share/67f18460-1c1c-8010-bc57-9f3b683ec87a -# Branching +## 🚧Branching - [ ]  Create the feature/transportation-search branch based on develop -# DTO +## DTO In order to develop transportation search flow, three DTOs need to be created in the application layer. - [ ]  Create DTOs related to transportation search flow - 📂 Suggested Folder: Application/DTOs/City` - - ```cs public class CityDto { @@ -23,34 +24,35 @@ public class CityDto ``` 📂 Suggested Folder: Application/DTOs/Transportation - ```cs public class TransportationSearchRequestDto { public short? VehicleTypeId { get; init; } - public int? FromCityId { get; init; } - public int? ToCityId { get; init; } - public DateTime? StartDate { get; init; } - public DateTime? EndDate { get; init; } -} +public int? FromCityId { get; init; } +public int? ToCityId { get; init; } +public DateTime? StartDate { get; init; } +public DateTime? EndDate { get; init; } ``` ```cs public class TransportationSearchResultDto { public long Id { get; init; } - public required string CompanyTitle { get; init; } - public required string FromLocationTitle { get; init; } - public required string ToLocationTitle { get; init; } - public required string FromCityTitle { get; init; } - public required string ToCityTitle { get; init; } - public DateTime StartDateTime { get; init; } - public DateTime? EndDateTime { get; init; } - public decimal Price { get; init; } -} +public int VehicleTypeId { get; init; } +public string? VehicleTitle { get; init; } +public required string CompanyTitle { get; init; } +public required string FromLocationTitle { get; init; } +public required string ToLocationTitle { get; init; } +public required string FromCityTitle { get; init; } +public required string ToCityTitle { get; init; } +public DateTime StartDateTime { get; init; } +public DateTime? EndDateTime { get; init; } +public decimal Price { get; init; } +public int RemainingCapacity { get; init; } + ``` -# Repository +## Repository There are a few things to be add to some repositories for transportation search flow. - [ ] Create DTOs related to transportation search flow @@ -108,7 +110,7 @@ public class TransportationRepository : ``` -# Auto Mapper +## Auto Mapper Auto Mapper simplifies mapping between aggregates and DTOs in both directions. - [ ] Create a `MappingProfile` that inherits `Profile`, and use it to add configurations for mappings @@ -157,7 +159,7 @@ public class MappingProfile : Profile . ``` -# Result & Result Status +## Result & Result Status - [ ] Create `ResultStatus` enum and `Result` class 📂 Suggested Folder: Application/Result @@ -220,22 +222,18 @@ public enum ResultStatus You can read more about enums: [W3Schools](https://www.w3schools.com/cs/cs_enums.php) -# `IService` & Service +## `IService` & Service Now, use `I[Entity]Repositry` and `IUnitOfWork` in services to implement business logic - - [ ] Create `I[Entity]Service` and `[Entity]Service` which implements it 📂 Suggested Folder for `I[Entity]Service`: Application/Interfaces 📂 Suggested Folder for Services: Application/Services - - - existence of an interface for each service class is optional - services can have multiple repositories in them -> logic-based structure An example of `I[Entity]Service`: - ```c# public interface ITransportationService { @@ -244,7 +242,6 @@ public interface ITransportationService ``` An example of `[Entity]Service`: - ```cs public class TransportationService : ITransportationService { @@ -291,7 +288,7 @@ builder.Services.AddScoped(); . ``` -# Controller +## Controller Now we're getting to endpoints, you should communicate with client side through web-api. So every controller uses Services in Application layer to receive requests and send responses with DTOs. - [ ] Create an APIController (right click on the folder, and then under Add, select Controller, and then make sure to select the APIController type) @@ -336,17 +333,16 @@ public class TransportationController : ControllerBase } ``` -- HttpGet: handles a GET request from client -> important for routing -- Ok, BadRequest, NotFound and StatusCode are Json results to send through api -- Use TransportationService to communicate with Application +- `HttpGet`: handles a GET request from client -> important for routing +- Ok, `BadRequest`, `NotFound` and `StatusCode` are json results to send through API +- Use `TransportationService` to communicate with Application -# Inserting Sample Data +## Inserting Sample Data For testing purposes, add some data into the related tables. You are provided with a SQL script, that adds some sample data into the following tables **Important Notes:** Note that different database names, and different table names will produce errors while executing the script. Consider adjusting these names before executing the script - - Cities - Companies - LocationTypes @@ -356,8 +352,14 @@ You are provided with a SQL script, that adds some sample data into the followin - Transportation - [ ] Open `TransportationRelatedSampleData.sql` with SSMS, and execute the query +> Note: there has been changes in database structure since this note and this file has been written. -# Merge +## 🚧Merge - [ ] Create a PR and merge the current branch with develop +# 🧠 Hints & Notes +# 🙌 Acknowledgements + +- ChatGPT for snippet refinement and explanations +# 🔍 References