├── .gitignore
├── Azon.Business.Test
├── Azon.Business.Test.csproj
├── CatalogServiceTests.cs
├── MockProductRepository.cs
└── OrderingTests.cs
├── Azon.Business
├── Azon.Business.csproj
├── BlueCustomerDiscountStrategy.cs
├── CatalogService.cs
├── CustomerDiscountStrategyFactory.cs
├── CustomerType.cs
├── DefaultDiscountStrategy.cs
├── GoldCustomerDiscountStrategy.cs
├── IDiscountStrategy.cs
├── IProductRepository.cs
├── InventoryProvider.cs
├── Order.cs
├── OrderingService.cs
├── Product.cs
├── ProductRepository.cs
└── Result.cs
├── Azon.WeatherLib
├── Azon.WeatherLib.csproj
├── City.cs
├── Reporter.cs
└── Temperature.cs
├── Azon.Web.Component
├── Azon.Web.Component.csproj
├── Button.cs
├── ButtonBase.cs
├── CheckBox.cs
├── Control.cs
├── DbConnector.cs
├── Form.cs
├── GridBox.cs
├── Label.cs
├── LinkButton.cs
└── RadioButton.cs
├── Azon.Web.Editor
├── Azon.Web.Editor.csproj
└── Program.cs
├── Azon.Web.Persistence
├── Azon.Web.Persistence.csproj
├── CsvPersistence.cs
├── OraclePersistence.cs
└── SqlServerPersistence.cs
├── Azon.Web.Sdk
├── Azon.Web.Sdk.csproj
├── Components
│ ├── Button.cs
│ ├── ButtonBase.cs
│ ├── CheckBox.cs
│ ├── Control.cs
│ ├── DbConnector.cs
│ ├── Form.cs
│ ├── GridBox.cs
│ ├── Label.cs
│ ├── LinkButton.cs
│ └── RadioButton.cs
└── Contracts
│ ├── IDatabasePersistence.cs
│ ├── IDrawable.cs
│ ├── IFilePersistence.cs
│ └── IPersistence.cs
├── Chapter00
├── Chapter00.csproj
├── Data.json
└── Program.cs
├── Chapter01
├── Chapter01.csproj
├── Model
│ ├── Car.cs
│ ├── IpInfo.cs
│ └── ProductColor.cs
└── Program.cs
├── Chapter02
├── Chapter02.csproj
├── Program.cs
└── UI
│ └── View
│ └── Terminal.cs
├── Chapter03
├── Chapter03.csproj
├── GameWorld.cs
├── HttpManager.cs
└── Program.cs
├── Chapter04
├── AbstractSampleApplication.cs
├── Chapter04.csproj
├── InterfaceSampleApplication.cs
├── InterfaceSeperation.cs
└── Program.cs
├── Chapter05
├── Chapter05.csproj
├── Components
│ ├── Button.cs
│ ├── ButtonBase.cs
│ ├── CheckBox.cs
│ ├── Control.cs
│ ├── DbConnector.cs
│ ├── GridBox.cs
│ ├── Label.cs
│ ├── LinkButton.cs
│ └── RadioButton.cs
├── Containers
│ └── Form.cs
├── Contracts
│ ├── IDrawable.cs
│ └── IPersistence.cs
├── Persistence
│ ├── CsvPersistence.cs
│ └── DbPersistence.cs
└── Program.cs
├── Chapter06
├── Chapter06.csproj
├── Dto
│ ├── ButtonBaseDto.cs
│ ├── ButtonDto.cs
│ ├── CheckBoxDto.cs
│ ├── ControlDto.cs
│ ├── DbConnectorDto.cs
│ ├── GridBoxDto.cs
│ ├── LabelDto.cs
│ ├── LinkButtonDto.cs
│ ├── PictureBoxDto.cs
│ └── RadioButtonDto.cs
├── Persistence
│ ├── ControlMapper.cs
│ └── JsonPersistence.cs
├── PictureBox.cs
└── Program.cs
├── Chapter08
├── Chapter08.csproj
├── Program.cs
├── Scenario00.cs
├── Scenario01.cs
└── StingExtensions.cs
├── Chapter09
├── Chapter09.csproj
├── EventSample.cs
├── Program.cs
└── StockService.cs
├── Chapter10
├── Chapter10.csproj
├── ColumnAttribute.cs
├── DataType.cs
├── MigrationProvider.cs
├── Model
│ ├── EntityBase.cs
│ └── Product.cs
├── Program.cs
└── TableAttribute.cs
├── FinalExam.md
├── FreeZone
├── Azon.Games
│ ├── Azon.Games.csproj
│ ├── Catalog.cs
│ ├── Category.cs
│ └── Game.cs
├── Learning.Abstractions
│ ├── ConsoleLogger.cs
│ ├── ElasticLogger.cs
│ ├── ILogger.cs
│ ├── InvalidRoleException.cs
│ ├── Learning.Abstractions.csproj
│ ├── Member.cs
│ ├── MemberRole.cs
│ ├── Program.cs
│ └── RoleProvider.cs
├── Learning.ExtensionMethods
│ ├── Learning.ExtensionMethods.csproj
│ ├── NumberExtensions.cs
│ ├── Program.cs
│ └── StringExtensions.cs
├── Learning.Generics
│ ├── IRepository.cs
│ ├── InMemoryRepository.cs
│ ├── Learning.Generics.csproj
│ └── Program.cs
├── Learning.Interfaces
│ ├── Category.cs
│ ├── Learning.Interfaces.csproj
│ ├── Player.cs
│ ├── Product.cs
│ ├── Program.cs
│ ├── Temperature.cs
│ └── World.cs
├── Learning.LINQ
│ ├── GameQueries.cs
│ ├── GameQueriesV2.cs
│ ├── Learning.LINQ.csproj
│ └── Program.cs
├── Learning.Loops
│ ├── Learning.Loops.csproj
│ ├── Program.cs
│ └── Terminal.cs
├── Learning.SOLID
│ ├── Basics
│ │ ├── DIP
│ │ │ ├── BadPractice.cs
│ │ │ ├── GoodPractice.cs
│ │ │ └── MultiUsagePractice.cs
│ │ ├── ISP
│ │ │ ├── BadPractice.cs
│ │ │ └── GoodPractice.cs
│ │ ├── LSP
│ │ │ ├── BadPractice.cs
│ │ │ └── GoodPractice.cs
│ │ ├── OCP
│ │ │ ├── BadPractice.cs
│ │ │ └── GoodPractice.cs
│ │ └── SRP
│ │ │ ├── BadPractice.cs
│ │ │ └── GoodPractice.cs
│ ├── Learning.SOLID.csproj
│ └── Program.cs
├── Learning.Structs.Client
│ ├── Learning.Structs.Client.csproj
│ └── Program.cs
├── Learning.Structs
│ ├── ComplexNumber.cs
│ ├── Learning.Structs.csproj
│ ├── Square.cs
│ └── Vector2D.cs
└── RobotFactory
│ ├── Factories
│ ├── IReportGenerator.cs
│ ├── IRobotFactory.cs
│ └── RobotFactory.cs
│ ├── Managers
│ └── TaskManager.cs
│ ├── Models
│ ├── AssemblyRobot.cs
│ ├── InspectionRobot.cs
│ ├── Robot.cs
│ └── TransportRobot.cs
│ ├── Program.cs
│ ├── Reports
│ └── ReportGenerator.cs
│ └── RobotFactory.csproj
├── LICENSE
├── Learning.Delegates
├── BasicSample.cs
├── EventSample.cs
├── Learning.Delegates.csproj
├── MulticastSample.cs
└── Program.cs
├── Midterm.md
├── Practices
├── Orange
│ └── O01
│ │ ├── CsvWriter.cs
│ │ ├── DatabaseWriter.cs
│ │ ├── GameEntity.cs
│ │ ├── GameState.dat
│ │ ├── IPersistance.cs
│ │ ├── O01.csproj
│ │ ├── Program.cs
│ │ └── World.cs
└── Yellow
│ ├── Y00
│ ├── Book.cs
│ ├── Category.cs
│ ├── Program.cs
│ ├── Topic.cs
│ └── Y00.csproj
│ ├── Y01
│ ├── Program.cs
│ ├── Vector2D.cs
│ └── Y01.csproj
│ ├── Y02
│ ├── Program.cs
│ └── Y02.csproj
│ ├── Y03
│ ├── HttpStatus.cs
│ ├── Program.cs
│ └── Y03.csproj
│ ├── Y04
│ ├── Program.cs
│ ├── Terminal.cs
│ └── Y04.csproj
│ └── Y06
│ ├── Behaviors
│ └── IDrawable.cs
│ ├── Components
│ ├── AzonButton.cs
│ ├── AzonImageButton.cs
│ ├── AzonRadioButton.cs
│ └── BaseButton.cs
│ ├── Controllers
│ └── DrawController.cs
│ ├── Program.cs
│ └── Y06.csproj
├── ProgrammingWithCSharp.sln
└── README.md
/Azon.Business.Test/Azon.Business.Test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 |
8 | false
9 | true
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/Azon.Business.Test/CatalogServiceTests.cs:
--------------------------------------------------------------------------------
1 | using Moq;
2 |
3 | namespace Azon.Business.Test;
4 |
5 | public class CatalogServiceTests
6 | {
7 | [Fact]
8 | public void GetTotalPrice_Should_Return_Sum_Of_Product_Prices()
9 | {
10 | /*
11 | CatalogService bileşeninin kullandığı ProductRepository bileşeni normal şartlarda
12 | veritabanına gidiyor olsun?
13 |
14 | Unit Test projelerinin çalıştığı ortamlar genellikle veritabanı, dış servisler, fiziki
15 | diskler veya ftp gibi alanlara erişmez/erişilmezi istenmez. Bu gibi durumlarda şu soru
16 | ortaya çıkar;
17 |
18 | Veritabanına erişemeyen bir test projesinde veritabanı bağımlılığı olan bir component'in
19 | dahil olduğu business fonksiyon nasıl test edilir?
20 | */
21 | // Arange
22 | // var productRepository=new ProductRepository();
23 | var mockProductRepository = new MockProductRepository();
24 | var catalogService = new CatalogService(mockProductRepository);
25 |
26 | // Act
27 | var actual = catalogService.GetTotalPrice();
28 |
29 | // Assert
30 | Assert.Equal(1014.49M, actual);
31 | }
32 | [Fact]
33 | public void GetTotalPrice_Should_Return_Valid_Total()
34 | {
35 | /*
36 | Bu örnekte Mock Framework olarak Moq isimli Nuget paketini kullanıyoruz.
37 | Manage Nuget Pacakges ile eklenebilir.
38 | dotnet komut satırı aracı ile de yüklenebilir.
39 | Proje dosyasına elle eklenerek de yüklenebilir.
40 | */
41 |
42 | // Arange
43 |
44 | // IProductRepository için bir Mock nesne kullanmak istediğimizi aşağıdaki ifade eile belirtiyoruz
45 | var mockRepository = new Mock();
46 | var products = new List()
47 | {
48 | new() {Id=1,Name="Ultravide geniş mi geniş LCD ekran",ListPrice=1000M},
49 | new() {Id=2,Name="Programming With C#",ListPrice=15M}
50 | };
51 | /*
52 | Setup ile hangi metodu çağıracağımızı ve Returns ile de bu metot çağrıldığında
53 | geriye ne döneceğini belirtiyoruz
54 | */
55 | mockRepository
56 | .Setup(f => f.GetProducts())
57 | .Returns(products);
58 |
59 | // Act
60 | var service = new CatalogService(mockRepository.Object);
61 | var actual = service.GetTotalPrice();
62 |
63 | // Assert
64 | Assert.Equal(1015, actual);
65 | }
66 | }
--------------------------------------------------------------------------------
/Azon.Business.Test/MockProductRepository.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Business.Test;
2 |
3 | /*
4 | CatalogService' in ihtiyaç duyduğu IProductRepository yerine geçen bir Mock nesne sınıfı.
5 | Veritabanına bağlanıp bir ürün listesi çekmemizi sağlayan davranışı taklit eder.
6 | Böylece gerçek anlamda veritabanına erişmeden asıl test etmek istediğimiz fonksiyonellik için
7 | gerekli bileşeni tesis edebiliriz.
8 |
9 | Elbette her durumda bu şekilde soyutlamalara ait implementasyonları yapmamız şart değildir.
10 | Mock Framework'ler bu işleri oldukça kolaylaştırır.
11 | */
12 | public class MockProductRepository
13 | : IProductRepository
14 | {
15 | public IEnumerable GetProducts()
16 | {
17 | return new List
18 | {
19 | new Product{Id=1,Name="Ultravide geniş mi geniş LCD ekran",ListPrice=999.99M},
20 | new Product{Id=2,Name="Programming With C#",ListPrice=14.50M}
21 | };
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Azon.Business.Test/OrderingTests.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Business.Test;
2 |
3 | /*
4 | Basit bir sipariş yönetim(OrderingService) bileşeni(servisi) düşünelim.
5 | Bu servis müşterinin tipine(CustomerType) göre sipariş üzerinde belli oradan indirim(Discount) uyguluyor.
6 | Bu fonksiyonellikle ilişkili birim testleri uygulamak istiyoruz.
7 |
8 | Müşteri türü Gold ise %10 indirim uygulanır.
9 | Müşteri türü Blue ise %5 indirim uygulanır.
10 | Diğer müşteri türlerinde bir indirim uygulanmaz.
11 | Sonradan sisteme başka müşteri türleri de eklenebilir.
12 | Sipariş tutarı belli bir değerin altında olanlar için hiçbir indirim uygulanmaz gibi.
13 |
14 | Aşağıdaki kodu TDD'nin, Red Green Blue prensibine göre yazıyoruz.
15 |
16 | Red (Fail), Önce fail etsin.
17 | Green (Success), Sonra çalışır ve doğru sonucu döndürür hale gelsin.
18 | Blue (Refactor), Kod iyileştirilsin
19 | */
20 | public class OrderingTests
21 | {
22 | /*
23 | Fact aslında bir Attribute tipidir. Attribute tipleri, runtime'a ekstra bilgi
24 | sağlamak için kullanılır(Metadata Programming kapsamında da düşünülebilir)
25 | Örneğin aşağıdaki metotların VS IDE' sindeki Test Explorer çıkıyor olması
26 | Fact attribute ile işaretlenmelerine bağlıdır.
27 | */
28 | [Fact]
29 | public void CalculateTotal_ShouldNotApplyDiscount_ForNullOrder()
30 | {
31 | // Arange
32 | Order order = null;
33 | var orderService = new OrderingService();
34 |
35 | // Act
36 | var result = orderService.CalculateTotal(order);
37 |
38 | // Assert
39 | Assert.False(result.IsSuccess);
40 | Assert.Equal("Invalid Order", result.ErrorMessage);
41 | }
42 |
43 | [Fact]
44 | public void CalculateTotal_ShouldApplyDiscount_ForGoldCustomer()
45 | {
46 | // Arange
47 | var order = new Order
48 | {
49 | Id = 1001,
50 | Amount = 99.99M,
51 | CustomerType = CustomerType.Gold
52 | };
53 |
54 | var orderService = new OrderingService();
55 |
56 | // Act
57 | var result = orderService.CalculateTotal(order);
58 |
59 | // Assert
60 | Assert.True(result.IsSuccess);
61 | Assert.Equal(89.991M, result.Value);
62 | }
63 |
64 | [Fact]
65 | public void CalculateTotal_ShouldApplyDiscount_ForBlueCustomer()
66 | {
67 | // Arange
68 | var order = new Order
69 | {
70 | Id = 1001,
71 | Amount = 99.99M,
72 | CustomerType = CustomerType.Blue
73 | };
74 |
75 | var orderService = new OrderingService();
76 |
77 | // Act
78 | var result = orderService.CalculateTotal(order);
79 |
80 | // Assert
81 | Assert.True(result.IsSuccess);
82 | Assert.Equal(94.9905M, result.Value);
83 | }
84 |
85 | [Fact]
86 | public void CalculateTotal_ShouldNotApply_ForStandardCustomerType()
87 | {
88 | // Arange
89 | var order = new Order
90 | {
91 | Id = 1002,
92 | Amount = 100M,
93 | CustomerType = CustomerType.Standard
94 | };
95 |
96 | var orderService = new OrderingService();
97 |
98 | // Act
99 | var result = orderService.CalculateTotal(order);
100 |
101 | // Assert
102 | Assert.Equal(order.Amount, result.Value);
103 | }
104 |
105 | }
--------------------------------------------------------------------------------
/Azon.Business/Azon.Business.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Azon.Business/BlueCustomerDiscountStrategy.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Business;
2 |
3 | public class BlueCustomerDiscountStrategy
4 | : IDiscountStrategy
5 | {
6 | public decimal Apply(decimal amount)
7 | {
8 | return amount * 0.95M;
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/Azon.Business/CatalogService.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Business;
2 |
3 | public class CatalogService
4 | {
5 | private readonly IProductRepository _productRepository;
6 |
7 | public CatalogService(IProductRepository productRepository)
8 | {
9 | _productRepository = productRepository;
10 | }
11 |
12 | public decimal GetTotalPrice()
13 | {
14 | var products = _productRepository.GetProducts();
15 | return products.Sum(p => p.ListPrice);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Azon.Business/CustomerDiscountStrategyFactory.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Business;
2 |
3 | /*
4 | OrderingService sınıfındaki CalculateTotal metodu, CustomerType değerine göre bir indirim uygular.
5 | Aslında bu indirim, IDiscountStrategy türeli nesneler tarafından yapılır.
6 | Zira OrderingService yeni indirim stratejileri kullanabilir veya var olanlar değişebilir.
7 | Open Closed ilkesine göre değişikliğe kapalı genişlemeye açık olması gerekir.
8 |
9 | Aşağıdaki Factory sınıfı ise, OrderingService'in ihtiyaç duyduğu noktada gereken IDiscountStrategy
10 | implementasyonunu almasını sağlar.
11 | */
12 | public static class CustomerDiscountStrategyFactory
13 | {
14 | public static IDiscountStrategy GetDiscountStrategy(CustomerType customerType)
15 | {
16 | //var strategies = new Dictionary()
17 | //{
18 | // {CustomerType.Gold ,new GoldCustomerDiscountStrategy()},
19 | // {CustomerType.Gold ,new BlueCustomerDiscountStrategy()},
20 | // {CustomerType.Blue ,new BlueCustomerDiscountStrategy()},
21 | //};
22 |
23 | return customerType switch
24 | {
25 | CustomerType.Gold => new GoldCustomerDiscountStrategy(),
26 | CustomerType.Blue => new BlueCustomerDiscountStrategy(),
27 | _ => new DefaultDiscountStrategy(),
28 | };
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Azon.Business/CustomerType.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Business;
2 |
3 | public enum CustomerType
4 | {
5 | Gold,
6 | Blue,
7 | Standard
8 | }
9 |
--------------------------------------------------------------------------------
/Azon.Business/DefaultDiscountStrategy.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Business;
2 |
3 | public class DefaultDiscountStrategy
4 | : IDiscountStrategy
5 | {
6 | public decimal Apply(decimal amount)
7 | {
8 | return amount;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Azon.Business/GoldCustomerDiscountStrategy.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Business;
2 |
3 | public class GoldCustomerDiscountStrategy
4 | : IDiscountStrategy
5 | {
6 | public decimal Apply(decimal amount)
7 | {
8 | return amount * 0.9M;
9 | }
10 |
11 | //public decimal Apply(Order order)
12 | //{
13 | // // OrderId için tabloya git bilgileri yükle
14 | // // OrderId'ye ait Customer tipini yakala
15 | // // CustomerTipi için tanımlı indirimleri almak üzere parametre tablosuna git
16 | // // İndirimleri uygula
17 |
18 | // return 0;
19 | //}
20 | }
21 |
--------------------------------------------------------------------------------
/Azon.Business/IDiscountStrategy.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Business;
2 |
3 | public interface IDiscountStrategy
4 | {
5 | decimal Apply(decimal amount);
6 | }
7 |
--------------------------------------------------------------------------------
/Azon.Business/IProductRepository.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Business;
2 |
3 | public interface IProductRepository
4 | {
5 | IEnumerable GetProducts();
6 | }
7 |
--------------------------------------------------------------------------------
/Azon.Business/InventoryProvider.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Business;
2 |
3 | /*
4 | Chapter08'de ele alınacak örnek kodlar.
5 | InventoryProvider sınıfı için gerekli olan birim test metotları yazılacak. Senaryolarımız aşağıdaki gibi;
6 |
7 | - AddProduct_ShouldThrowException_WhenProductAlreadyExists. Ürün ekleme (AddProduct) testi. Ürün zaten stokta ise hata vermesi.
8 | - UpdateStock_ShouldReturnError_WhenProductNotFound. Ürün bulunamadığında hata döndürülmesi.
9 | - UpdateStock_ShouldFail_WhenStockIsInsufficient. Stok azalma sırasında yetersiz stok hatası verilmesi.
10 | - UpdateStock_ShouldFail_WhenExceedingMaxStockLimit. Maksimum stok limiti aşıldığında hata dönülmesi.
11 | - UpdateStock_ShouldUpdateCorrectly_WhenStockIsValid. Geçerli bir işlemde stok miktarının doğru güncellenmesi.
12 |
13 | */
14 |
15 | public class InventoryItem
16 | {
17 | public string ProductId { get; set; }
18 | public string Title { get; set; }
19 | public int Stock { get; set; }
20 | public int MaxStock { get; set; }
21 | }
22 |
23 | public class InventoryProvider
24 | {
25 | private readonly Dictionary _inventory = new();
26 |
27 | public void AddProduct(string productId, string title, int maxStock)
28 | {
29 | if (_inventory.ContainsKey(productId))
30 | {
31 | throw new InvalidOperationException("Ürün zaten mevcut.");
32 | }
33 |
34 | _inventory[productId] = new InventoryItem
35 | {
36 | ProductId = productId,
37 | Title = title,
38 | MaxStock = maxStock,
39 | Stock = 0
40 | };
41 | }
42 |
43 | public string UpdateStock(string productId, int quantity)
44 | {
45 | if (!_inventory.TryGetValue(productId, out InventoryItem? item))
46 | {
47 | return "Ürün bulunamadı.";
48 | }
49 |
50 | if (quantity < 0 && Math.Abs(quantity) > item.Stock)
51 | {
52 | return "Yetersiz stok.";
53 | }
54 |
55 | if (quantity > 0 && (item.Stock + quantity) > item.MaxStock)
56 | {
57 | return "Maksimum stok limiti aşıldı.";
58 | }
59 |
60 | item.Stock += quantity;
61 | return "Stok güncellendi.";
62 | }
63 |
64 | public int GetStock(string productId)
65 | {
66 | if (!_inventory.ContainsKey(productId))
67 | {
68 | throw new InvalidOperationException("Ürün bulunamadı.");
69 | }
70 |
71 | return _inventory[productId].Stock;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/Azon.Business/Order.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Business;
2 |
3 | /*
4 | Order nesnesinin üretilmesinde Creational Design Pattern'lardan hangilerini kullanabiliriz.
5 | TODO@buraksenyurt Order sınıfı için bir örnek yapalım.
6 | */
7 | public class Order
8 | {
9 | public int Id { get; set; }
10 | public decimal Amount { get; set; }
11 | public CustomerType CustomerType { get; set; }
12 | }
--------------------------------------------------------------------------------
/Azon.Business/OrderingService.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Business;
2 |
3 | public class OrderingService
4 | {
5 | public Result CalculateTotal(Order order)
6 | {
7 | if (order == null)
8 | {
9 | return new Result
10 | {
11 | IsSuccess = false,
12 | Value = 0,
13 | ErrorMessage = "Invalid Order"
14 | };
15 | }
16 |
17 | /*
18 | Aşağıdaki ifadede CustomerType değerine bir IDiscountStrategy türevli gerçek nesneyi(Concrete Object) alıyoruz
19 | ve onun Apply metodunu uyguluyoruz.
20 | */
21 | var discountStrategy = CustomerDiscountStrategyFactory.GetDiscountStrategy(order.CustomerType);
22 | var total = discountStrategy.Apply(order.Amount);
23 |
24 | //switch (order.CustomerType)
25 | //{
26 | // case CustomerType.Gold:
27 | // total = order.Amount * 0.9M;
28 | // break;
29 | // case CustomerType.Blue:
30 | // total = order.Amount * 0.95M;
31 | // break;
32 | //}
33 |
34 | return new Result
35 | {
36 | Value = total,
37 | IsSuccess = true,
38 | };
39 | }
40 | }
--------------------------------------------------------------------------------
/Azon.Business/Product.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Business;
2 |
3 | public class Product
4 | {
5 | public int Id { get; set; }
6 | public string Name { get; set; }
7 | public decimal ListPrice { get; set; }
8 | }
9 |
--------------------------------------------------------------------------------
/Azon.Business/ProductRepository.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Business;
2 |
3 | public class ProductRepository
4 | : IProductRepository
5 | {
6 | public IEnumerable GetProducts()
7 | {
8 | // Burada gerçekten bir veritabanına gidip Product listesinin çekildiğini var sayıyoruz
9 | return [];
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Azon.Business/Result.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Business;
2 |
3 | public class Result
4 | {
5 | public bool IsSuccess { get; set; }
6 | public string ErrorMessage { get; set; } = string.Empty;
7 | public required T Value { get; set; }
8 | }
9 |
--------------------------------------------------------------------------------
/Azon.WeatherLib/Azon.WeatherLib.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Azon.WeatherLib/City.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.WeatherLib
2 | {
3 | public class City
4 | {
5 | public string Name { get; private set; }
6 | public Temperature Temperature { get; private set; }
7 | public City(string name, Temperature temperature)
8 | {
9 | // Validasyon işlemleri ele alınabilir
10 | Name = name;
11 | Temperature = temperature;
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Azon.WeatherLib/Reporter.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.WeatherLib
2 | {
3 | /*
4 | Bir sınıf kütüphanesi içerisinde anlamsal bütünlüğü bozmadan istediğimiz kadar tip ve tip üyesi ekleyebiliriz.
5 | Aşağıdaki sınıfın şehir bazı sıcaklık değerlerini tutan bir yapıda olduğunu varsayalım.
6 | İçinde şehir ve sıcaklık değerlerini taşıyacak bir kaba sahip olabilir.
7 | Bu bir array olabilir ya da key:value gibi çalışacak bir Dictionary veri yapısı olabilir veya kolayca genişleyebilen bir koleksiyon.
8 | Bir başka deyişle List, Dictionary, Array gibi veri modelleri birden fazla şehir,sıcaklık bilgisi için tasarlanabilir.
9 | */
10 | public class Reporter
11 | {
12 | // private City[] cities = new City[10];
13 | // İçerisinde City türünden elemanlar barındıracak bir List koleksiyonu.
14 | private List cityList = [];
15 |
16 | public void AddCity(City city)
17 | {
18 | cityList.Add(city);
19 | }
20 | public City GetCity(string cityName)
21 | {
22 | // GetCity metodu kullanılmak istendiğinde çalışma zamanın NotImplementedException fırlatılır(throw)
23 | // Exception nesneler try...catch blokları ile yakalanmazlarsa program crash olur
24 | // Biz burada "Henüz bu metot tamamlanmadı" manasında kullanmak istedik.
25 | throw new NotImplementedException();
26 | }
27 | public List GetCityList()
28 | {
29 | return cityList;
30 | }
31 | public Temperature GetTemperature(string cityName)
32 | {
33 | /*
34 | Yeni eklenmeiş ama henüz içeriği yazılmamış metotlar söz konusu olduğunda,
35 | diğer programcıların veya object user'ların bu durumdan haberdar olması adına da
36 | NotImplementeException kullanılabilir.
37 |
38 | throw ile çalışma zamanına (runtime) bir Exception nesnesi fırlatılabilir.
39 | new ile başlayan kısım Exception nesne örneğidir.
40 | Bu exception nesneleri bir try...catch mekanizması ile yakalanarak kontrol altına alınabilir.
41 | */
42 | throw new NotImplementedException();
43 | }
44 |
45 | // Tüm kayıtlı şehirlerdeki anlık sıcaklık bilgilerini string formatta döndüren bir metot
46 | public string GetSummary()
47 | {
48 | throw new NotImplementedException();
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Azon.WeatherLib/Temperature.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.WeatherLib
2 | {
3 | /*
4 | Class Library'ler execute edilebilen assembly'lar değildir. Console uygulamalarının aksine.
5 | Diğer projelerin referans ederek kullanabileceği fonksiyonellikler, türleri vs barındırırlar.
6 |
7 | Temperature sınıfındaki amaç hava sıcaklık değerini taşıyan bir veri yapısı sağlamaktır.
8 | Sahip olması gereken işlevler. Fahrenheit to Celcius vice versa.
9 |
10 |
11 | Öneri Senaryo : Belli sıcaklık değerlerine göre bir state bildirimi (Ilık, Serin, Sıcak, Nemli)
12 | */
13 | public struct Temperature
14 | {
15 | public double Value { get; set; }
16 | public TemperatureType Type { get; set; }
17 | public Temperature(double value, TemperatureType type)
18 | {
19 | Value = value;
20 | Type = type;
21 | }
22 |
23 | public void ConvertToCelcius()
24 | {
25 | // Early Return
26 | // Yani kod akışından erken dönülebilme olasılığı varsa uygulayalım.
27 | if (Type == TemperatureType.Celcius)
28 | return;
29 |
30 | Type = TemperatureType.Celcius;
31 | Value = (Value - 32) * 5.0 / 9.0;
32 | }
33 | public void ConvertToFahrenheit()
34 | {
35 | if (Type == TemperatureType.Celcius)
36 | {
37 | Type = TemperatureType.Fahrenheit;
38 | Value = (Value * 9.0 / 5.0) + 32;
39 | }
40 | }
41 |
42 | //public double ConvertToCelcius()
43 | //{
44 | // // Early Return
45 | // // Yani kod akışından erken dönülebilme olasılığı varsa uygulayalım.
46 | // if (Type == TemperatureType.Celcius)
47 | // return Value;
48 |
49 | // Type = TemperatureType.Celcius;
50 | // return (Value - 32) * 5.0 / 9.0;
51 |
52 | // //if (Type == TemperatureType.Fahrenheit)
53 | // //{
54 | // // Type = TemperatureType.Celcius;
55 | // // return (Value - 32) * 5.0 / 9.0;
56 | // //}
57 | // //return Value;
58 | //}
59 |
60 | //public double ConvertToFahrenheit()
61 | //{
62 | // if (Type == TemperatureType.Celcius)
63 | // {
64 | // Type = TemperatureType.Fahrenheit;
65 | // return (Value * 9.0 / 5.0) + 32;
66 | // }
67 | // return Value;
68 | //}
69 | public override string ToString()
70 | {
71 | return $"{Value} ({Type})";
72 | }
73 | }
74 | public enum TemperatureType
75 | {
76 | Celcius,
77 | Fahrenheit
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/Azon.Web.Component/Azon.Web.Component.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Azon.Web.Component/Button.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Web.Component;
2 |
3 | public class Button(int id, string name, (double, double) position)
4 | : ButtonBase(id, name, position), IDrawable
5 | {
6 | protected bool IsCorneredCurve { get; set; }
7 | public string? Text { get; set; }
8 |
9 | public void Draw()
10 | {
11 | Console.WriteLine("Button draw at {0}:{1}", Position.Item1, Position.Item2);
12 | }
13 | public override string ToString()
14 | {
15 | return $"{base.ToString()}|{Text}|{IsCorneredCurve}";
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Azon.Web.Component/ButtonBase.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Web.Component;
2 |
3 | public abstract class ButtonBase(int id, string name, (double, double) position)
4 | : Control(id, name, position)
5 | {
6 | public string? BackgroundColor { get; set; }
7 | public string? ForegroundColor { get; set; }
8 | }
9 |
--------------------------------------------------------------------------------
/Azon.Web.Component/CheckBox.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Web.Component;
2 |
3 | public class CheckBox(int id, string name, (double, double) position)
4 | : Control(id, name, position), IDrawable
5 | {
6 | public string? Text { get; set; }
7 | public bool IsChecked { get; set; }
8 |
9 | public void Draw()
10 | {
11 | Console.WriteLine("CheckBox draw at {0}:{1}", Position.Item1, Position.Item2);
12 | }
13 | public override string ToString()
14 | {
15 | return $"{base.ToString()}|{Text}|{IsChecked}";
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Azon.Web.Component/Control.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Web.Component;
2 |
3 | public abstract class Control(int id, string name, (double, double) position)
4 | {
5 | public int Id { get; set; } = id;
6 | protected string? Name { get; set; } = name;
7 | protected (double, double) Position { get; set; } = position;
8 |
9 | public override string ToString()
10 | {
11 | return $"{Id}|{GetType().Name}|{Name}|{Position}";
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Azon.Web.Component/DbConnector.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Web.Component;
2 |
3 | public class DbConnector(int id, string name, (double, double) position)
4 | : Control(id, name, position)
5 | {
6 | public string? ConnectionString { get; set; }
7 |
8 | public override string ToString()
9 | {
10 | return $"{base.ToString()}|{ConnectionString}";
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Azon.Web.Component/Form.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Web.Component;
2 |
3 | public class Form(IPersistence persistence)
4 | {
5 | private readonly List _controls = [];
6 | private readonly IPersistence _persistence = persistence;
7 |
8 | public void AddControls(params Control[] controls)
9 | {
10 | _controls.AddRange(controls);
11 | }
12 | public void LocateAll()
13 | {
14 | foreach (Control control in _controls)
15 | {
16 | Console.WriteLine($"{control.Id} location set");
17 | }
18 | }
19 | public void DrawAll()
20 | {
21 | foreach (Control control in _controls)
22 | {
23 | if (control is IDrawable drawable)
24 | {
25 | drawable.Draw();
26 | }
27 | }
28 | }
29 |
30 | public void Save()
31 | {
32 | _persistence.Save(_controls);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Azon.Web.Component/GridBox.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Web.Component;
2 |
3 | internal class GridBox(int id, string name, (double, double) position)
4 | : Control(id, name, position), IDrawable
5 | {
6 | public int RowCount { get; set; }
7 | public int ColumnCount { get; set; }
8 |
9 | public void Draw()
10 | {
11 | Console.WriteLine("GridBox draw at {0}:{1}", Position.Item1, Position.Item2);
12 | }
13 | public override string ToString()
14 | {
15 | return $"{base.ToString()}|{RowCount}|{ColumnCount}";
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Azon.Web.Component/Label.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Web.Component;
2 |
3 | public class Label(int id, string name, (double, double) position)
4 | : Control(id, name, position), IDrawable
5 | {
6 | public string Text { get; set; }
7 |
8 | public void Draw()
9 | {
10 | Console.WriteLine("Label draw at {0}:{1}", Position.Item1, Position.Item2);
11 | }
12 | public override string ToString()
13 | {
14 | return $"{base.ToString()}|{Text}";
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Azon.Web.Component/LinkButton.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Web.Component;
2 |
3 | public class LinkButton(int id, string name, (double, double) position)
4 | : ButtonBase(id, name, position), IDrawable
5 | {
6 | public Uri Url { get; set; }
7 |
8 | public void Draw()
9 | {
10 | Console.WriteLine("LinkButton draw at {0}:{1}", Position.Item1, Position.Item2);
11 | }
12 | public override string ToString()
13 | {
14 | return $"{base.ToString()}|{Url}";
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Azon.Web.Component/RadioButton.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Web.Component;
2 |
3 | public class RadioButton(int id, string name, (double, double) position)
4 | : ButtonBase(id, name, position), IDrawable
5 | {
6 | public List Options { get; set; } = [];
7 | public string SelectedOption { get; set; }
8 |
9 | public void Draw()
10 | {
11 | Console.WriteLine("RadioButton draw at {0}:{1}", Position.Item1, Position.Item2);
12 | }
13 | public override string ToString()
14 | {
15 | return $"{base.ToString()}|{SelectedOption}";
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Azon.Web.Editor/Azon.Web.Editor.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Azon.Web.Editor/Program.cs:
--------------------------------------------------------------------------------
1 | using Azon.Web.Persistence;
2 | using Azon.Web.Sdk.Components;
3 |
4 | namespace Azon.Web.Editor;
5 |
6 | internal class Program
7 | {
8 | static void Main(string[] args)
9 | {
10 | var csvPersistence = new CsvPersistence();
11 | Form mainForm = new(csvPersistence);
12 |
13 | Button btnSave = new(101, "btnSave", (0, 100))
14 | {
15 | Text = "Save"
16 | };
17 | Button btnClose = new(102, "btnClose", (0, 500))
18 | {
19 | Text = "Close"
20 | };
21 | CheckBox chkIsActiveProfile = new(104, "chkIsActive", (0, 10))
22 | {
23 | Text = "Is Active Profile",
24 | IsChecked = true
25 | };
26 | Label lblTitle = new(106, "lblTitle", (50, 50))
27 | {
28 | Text = "Title"
29 | };
30 | LinkButton lnkAbout = new(204, "lnkAbout", (400, 50))
31 | {
32 | Url = new Uri("https://www.azon.com.tr/about")
33 | };
34 | DbConnector dbConnector = new(90, "dbConnector", (0, 0))
35 | {
36 | ConnectionString = "data source=localhost:database=Northwind;integrated security=sspi"
37 | };
38 |
39 | mainForm.AddControls(btnSave, btnClose, lblTitle, lnkAbout, chkIsActiveProfile, dbConnector);
40 | mainForm.DrawAll();
41 | mainForm.Save();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Azon.Web.Persistence/Azon.Web.Persistence.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Azon.Web.Persistence/CsvPersistence.cs:
--------------------------------------------------------------------------------
1 | using Azon.Web.Sdk.Components;
2 | using Azon.Web.Sdk.Contracts;
3 | using System.Text;
4 |
5 | namespace Azon.Web.Persistence;
6 |
7 | public class CsvPersistence
8 | : IFilePersistence
9 | {
10 | public string FilePath { get; set; } = Path.Combine(Environment.CurrentDirectory, "Form.dat");
11 | public void Save(List controls)
12 | {
13 | var builder = new StringBuilder();
14 | foreach (Control control in controls)
15 | {
16 | builder.AppendLine(control.ToString());
17 | }
18 | var content = builder.ToString();
19 | File.WriteAllText(FilePath, content);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Azon.Web.Persistence/OraclePersistence.cs:
--------------------------------------------------------------------------------
1 | using Azon.Web.Sdk.Components;
2 | using Azon.Web.Sdk.Contracts;
3 |
4 | namespace Azon.Web.Persistence;
5 |
6 | public class OraclePersistence
7 | :IDatabasePersistence
8 | {
9 | public string ConnectionString { get; set; }
10 | public string UserName { get; set; }
11 |
12 | public void Save(List controls)
13 | {
14 | Console.WriteLine("Database save");
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Azon.Web.Persistence/SqlServerPersistence.cs:
--------------------------------------------------------------------------------
1 | using Azon.Web.Sdk.Components;
2 | using Azon.Web.Sdk.Contracts;
3 |
4 | namespace Azon.Web.Persistence;
5 |
6 | public class SqlServerPersistence
7 | : IDatabasePersistence
8 | {
9 | public string ConnectionString { get; set ; }
10 | public string UserName { get ; set; }
11 |
12 | public void Save(List controls)
13 | {
14 | Console.WriteLine("Database save");
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Azon.Web.Sdk/Azon.Web.Sdk.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Azon.Web.Sdk/Components/Button.cs:
--------------------------------------------------------------------------------
1 | using Azon.Web.Sdk.Contracts;
2 |
3 | namespace Azon.Web.Sdk.Components;
4 |
5 | public class Button(int id, string name, (double, double) position)
6 | : ButtonBase(id, name, position), IDrawable
7 | {
8 | public bool IsCorneredCurve { get; set; }
9 | public string? Text { get; set; }
10 |
11 | public void Draw()
12 | {
13 | Console.WriteLine("Button draw at {0}:{1}", Position.Item1, Position.Item2);
14 | }
15 | public override string ToString()
16 | {
17 | return $"{base.ToString()}|{Text}|{IsCorneredCurve}";
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Azon.Web.Sdk/Components/ButtonBase.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Web.Sdk.Components;
2 |
3 | public abstract class ButtonBase(int id, string name, (double, double) position)
4 | : Control(id, name, position)
5 | {
6 | public string? BackgroundColor { get; set; }
7 | public string? ForegroundColor { get; set; }
8 | }
9 |
--------------------------------------------------------------------------------
/Azon.Web.Sdk/Components/CheckBox.cs:
--------------------------------------------------------------------------------
1 | using Azon.Web.Sdk.Contracts;
2 |
3 | namespace Azon.Web.Sdk.Components;
4 |
5 | public class CheckBox(int id, string name, (double, double) position)
6 | : Control(id, name, position), IDrawable
7 | {
8 | public string? Text { get; set; }
9 | public bool IsChecked { get; set; }
10 |
11 | public void Draw()
12 | {
13 | Console.WriteLine("CheckBox draw at {0}:{1}", Position.Item1, Position.Item2);
14 | }
15 | public override string ToString()
16 | {
17 | return $"{base.ToString()}|{Text}|{IsChecked}";
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Azon.Web.Sdk/Components/Control.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Web.Sdk.Components;
2 |
3 | public abstract class Control(int id, string name, (double, double) position)
4 | {
5 | public int Id { get; set; } = id;
6 | protected string? Name { get; set; } = name;
7 | protected (double, double) Position { get; set; } = position;
8 |
9 | public override string ToString()
10 | {
11 | return $"{Id}|{GetType().Name}|{Name}|{Position}";
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Azon.Web.Sdk/Components/DbConnector.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Web.Sdk.Components;
2 |
3 | public class DbConnector(int id, string name, (double, double) position)
4 | : Control(id, name, position)
5 | {
6 | public string? ConnectionString { get; set; }
7 |
8 | public override string ToString()
9 | {
10 | return $"{base.ToString()}|{ConnectionString}";
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Azon.Web.Sdk/Components/Form.cs:
--------------------------------------------------------------------------------
1 | using Azon.Web.Sdk.Contracts;
2 |
3 | namespace Azon.Web.Sdk.Components;
4 |
5 | public class Form(IPersistence persistence)
6 | {
7 | private readonly List _controls = [];
8 | private readonly IPersistence _persistence = persistence;
9 |
10 | public void AddControls(params Control[] controls)
11 | {
12 | _controls.AddRange(controls);
13 | }
14 | public void LocateAll()
15 | {
16 | foreach (Control control in _controls)
17 | {
18 | Console.WriteLine($"{control.Id} location set");
19 | }
20 | }
21 | public void DrawAll()
22 | {
23 | foreach (Control control in _controls)
24 | {
25 | if (control is IDrawable drawable)
26 | {
27 | drawable.Draw();
28 | }
29 | }
30 | }
31 |
32 | public void Save()
33 | {
34 | _persistence.Save(_controls);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Azon.Web.Sdk/Components/GridBox.cs:
--------------------------------------------------------------------------------
1 | using Azon.Web.Sdk.Contracts;
2 |
3 | namespace Azon.Web.Sdk.Components;
4 |
5 | public class GridBox(int id, string name, (double, double) position)
6 | : Control(id, name, position), IDrawable
7 | {
8 | public int RowCount { get; set; }
9 | public int ColumnCount { get; set; }
10 |
11 | public void Draw()
12 | {
13 | Console.WriteLine("GridBox draw at {0}:{1}", Position.Item1, Position.Item2);
14 | }
15 | public override string ToString()
16 | {
17 | return $"{base.ToString()}|{RowCount}|{ColumnCount}";
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Azon.Web.Sdk/Components/Label.cs:
--------------------------------------------------------------------------------
1 | using Azon.Web.Sdk.Contracts;
2 |
3 | namespace Azon.Web.Sdk.Components;
4 |
5 | public class Label(int id, string name, (double, double) position)
6 | : Control(id, name, position), IDrawable
7 | {
8 | public string Text { get; set; }
9 |
10 | public void Draw()
11 | {
12 | Console.WriteLine("Label draw at {0}:{1}", Position.Item1, Position.Item2);
13 | }
14 | public override string ToString()
15 | {
16 | return $"{base.ToString()}|{Text}";
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Azon.Web.Sdk/Components/LinkButton.cs:
--------------------------------------------------------------------------------
1 | using Azon.Web.Sdk.Contracts;
2 |
3 | namespace Azon.Web.Sdk.Components;
4 |
5 | public class LinkButton(int id, string name, (double, double) position)
6 | : ButtonBase(id, name, position), IDrawable
7 | {
8 | public Uri Url { get; set; }
9 |
10 | public void Draw()
11 | {
12 | Console.WriteLine("LinkButton draw at {0}:{1}", Position.Item1, Position.Item2);
13 | }
14 | public override string ToString()
15 | {
16 | return $"{base.ToString()}|{Url}";
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Azon.Web.Sdk/Components/RadioButton.cs:
--------------------------------------------------------------------------------
1 | using Azon.Web.Sdk.Contracts;
2 |
3 | namespace Azon.Web.Sdk.Components;
4 |
5 | public class RadioButton(int id, string name, (double, double) position)
6 | : ButtonBase(id, name, position), IDrawable
7 | {
8 | public List Options { get; set; } = [];
9 | public string SelectedOption { get; set; }
10 |
11 | public void Draw()
12 | {
13 | Console.WriteLine("RadioButton draw at {0}:{1}", Position.Item1, Position.Item2);
14 | }
15 | public override string ToString()
16 | {
17 | return $"{base.ToString()}|{SelectedOption}";
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Azon.Web.Sdk/Contracts/IDatabasePersistence.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Web.Sdk.Contracts;
2 |
3 | public interface IDatabasePersistence
4 | : IPersistence
5 | {
6 | string ConnectionString { get; set; }
7 | string UserName { get; set; }
8 | }
9 |
--------------------------------------------------------------------------------
/Azon.Web.Sdk/Contracts/IDrawable.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Web.Sdk.Contracts;
2 |
3 | public interface IDrawable
4 | {
5 | void Draw();
6 | }
7 |
--------------------------------------------------------------------------------
/Azon.Web.Sdk/Contracts/IFilePersistence.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Web.Sdk.Contracts
2 | {
3 | public interface IFilePersistence : IPersistence
4 | {
5 | string FilePath { get; set; }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/Azon.Web.Sdk/Contracts/IPersistence.cs:
--------------------------------------------------------------------------------
1 | using Azon.Web.Sdk.Components;
2 |
3 | namespace Azon.Web.Sdk.Contracts;
4 |
5 | /*
6 | Aşağıdaki arayüz generic hale çevrilmiştir. Yani T türü yerine herhangi bir tip gelebilir,
7 | arayüz içerisindeki üyelerde T görülen yerlere seçilen tip gelir.
8 |
9 | Buradaki senaryoda T türü için kısıt koymak gerekir (Generic Constraints)
10 | */
11 | //public interface IPersistence
12 | // // where T: class,new() // Burada T türünün bir sınıf olması ve mutlaka default constructor içermesi belirtiliyor
13 | // // where T : Control, IDrawable // Burada ise T türünün Control sınıfından türemiş olması ve IDrawable arayüzünü implemente etmiş olması gerektiği belirtiliyor
14 | // // where T : Control
15 | //{
16 | // void Save(List controls);
17 | //}
18 |
19 | public interface IPersistence
20 | {
21 | void Save(List controls);
22 | }
--------------------------------------------------------------------------------
/Chapter00/Chapter00.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
12 | PreserveNewest
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Chapter00/Data.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "d5e8b21d-4ec3-4723-aabe-cbb2dcd9d7f2",
4 | "title": "Inventory Tracking System",
5 | "summary": "Bu projede amaç basit bir envanter takip sistemi geliştirilmesidir.",
6 | "level": 70
7 | },
8 | {
9 | "id": "d9c41b8f-ecc4-4236-9538-8a6ad37d0ee3",
10 | "title": "Terminal-Based Dungeon Game",
11 | "summary": "Terminalden programın sorduğu sorulara göre oyuncuyu yönlendirilen bir zindan oyunudur. Tek level tasarlanması yeterlidir. Görsel bir öğe içermemektedir.",
12 | "level": 90
13 | },
14 | {
15 | "id": "c9235b47-076c-4d64-b42d-b57d39cfa6c8",
16 | "title": "Random Data Set Generator",
17 | "summary": "Hepimizin derdi bazen rastgele test verisi bulmak olur. Örnek ürün listeleri, kullanıcı profilleri gibi. Bu tip veri setlerini oluşturmayı kolaylaştıran bir programdır.",
18 | "level": 80
19 | },
20 | {
21 | "id": "e8fae5c8-62da-4eaa-9d35-8b06e49fb58f",
22 | "title": "Simple Abstract Syntax Tree (AST) Interpreter",
23 | "summary": "Oldukça basit seviyede bir dil yorumlayıcı programdır.",
24 | "level": 100
25 | },
26 | {
27 | "id": "bc7a7d32-8b09-4f8b-890d-5fd2b5c1d657",
28 | "title": "Lightweight API Gateway",
29 | "summary": "API Gateway prensiplerini içeren bir yönetim programıdır.",
30 | "level": 70
31 | },
32 | {
33 | "id": "6b6eb3c8-fdbf-4623-b6f7-1b309567f195",
34 | "title": "Backend Service Development for Kanban Board Applications",
35 | "summary": "Önyüz tarafında Kanban modelinde çalışan bir arayüz için gerekli fonksiyonellikleri sağlayan bir Web API'dir. Rest veya gRPC şeklinde çalıştırılabilir.",
36 | "level": 65
37 | },
38 | {
39 | "id": "d8a0c9ea-e4e2-4a3f-86a0-b2ee1b0df10e",
40 | "title": "Static Code Quality Analyzer",
41 | "summary": "Bir .net uygulama kodunu tarayıp belli başlı kod kalite metriklerini ölçümleyerek raporlayan bir araçtır.",
42 | "level": 100
43 | },
44 | {
45 | "id": "e9650eeb-961c-4887-bb55-4448c716e2f1",
46 | "title": "Data Transfer Application Between Different Sources",
47 | "summary": "Farklı kaynaklar arasında veri taşıması yapılmasını sağlayan yönetici uygulamadır. SSIS (Sql Server Integration Services) benzeri bir uygulamanın çok basit bir sürümüdür.",
48 | "level": 85
49 | },
50 | {
51 | "id": "05d5b8ae-e162-4e9a-bb44-72343aeea636",
52 | "title": "Radio Stations Program",
53 | "summary": "Internet üzerinden yayın yapan radyo programları için offline çalışan bir desktop uygulamasıdır.",
54 | "level": 60
55 | },
56 | {
57 | "id": "a370e8ef-2636-4f8d-9c4c-275238ed9b29",
58 | "title": "E-commerce Cart System",
59 | "summary": "Bir e-ticaret sistesinin sadece alışveriş sepeti modülünün geliştirilmesini içerir. Önyüz tasarımından ziyade arka plandaki model yapılarının tasarımı, bileşenler ve fonksiyonların içeriği önemlidir.",
60 | "level": 85
61 | },
62 | {
63 | "id": "e4ec7b69-e89c-46bf-8139-e1d40a2e9ee2",
64 | "title": "Library Management System (Nuget Clone)",
65 | "summary": "Burada Nuget benzeri bir paket yönetim sisteminin benzeri inşa edilir. Paket listeleme, versiyonlama, doküman desteği ve programlara indirebilme özelliklerinin olması yeterlidir.",
66 | "level": 90
67 | },
68 | {
69 | "id": "6b951e64-2f9c-46a4-93e3-bc09b119e3fa",
70 | "title": "Online Multi User Exam/Quiz Platform (Mentimeter Clone)",
71 | "summary": "Online platformda çalışan öğrenciler için soru setlerinin hazırlanabildiği bir web uygulamasıdır.",
72 | "level": 100
73 | },
74 | {
75 | "id": "ecb5e758-23b7-4e04-8e3a-477a2fe57b38",
76 | "title": "Employee Management System",
77 | "summary": "Hafifsiklet bir insan kaynakları yönetimi uygulamasıdır. Mavi yakalılar için tasarlanabilir. Organizasyon ağacı desteği olmalıdır.",
78 | "level": 65
79 | },
80 | {
81 | "id": "57f09776-bb1d-4a1c-92e7-726d5d96f2c6",
82 | "title": "Topic Based ChatBot Application",
83 | "summary": "Azure platformunun AI kabiliyetleri kullanılarak tasarlanacak ve platforma giren kullanıcılara yardım edebilecek bir chat bot uygulamasıdır.",
84 | "level": 75
85 | },
86 | {
87 | "id": "fc3b8d72-45ef-4a91-9713-5ba2e05e5e91",
88 | "title": "Stock Market Tracking and Analysis Program",
89 | "summary": "Piyasa verilerini analiz ederen bir takım sonuçlar üreten ve tavsiyelerde bulunan bir web uygulaması olarak düşünülebilir.",
90 | "level": 60
91 | },
92 | {
93 | "id": "7fdba578-bc6a-4d94-8583-4091c5d6c34e",
94 | "title": "Sequential Task Management System",
95 | "summary": "Bir sistemdeki planlı işleri çalışıtırıp, yönetiminin de yapılabildiği desktop uygulamasıdır. Web tabanlı olarak da tasarlanabilir.",
96 | "level": 90
97 | },
98 | {
99 | "id": "22bf3e68-2077-4d0e-9b9b-015e7b13e4c2",
100 | "title": "Real-Time Data Processing Service",
101 | "summary": "Bir veri setini gerçek zamanlı olarak analiz edip sonuç çıkartan servis uygulamasıdır. Performans öncelikli bir uygulama olduğu için paralel çalıştırma veya multitasking gibi özellikler öne çıkar.",
102 | "level": 100
103 | },
104 | {
105 | "id": "55b18938-7f9c-43ff-9b40-f3b3e70e08d3",
106 | "title": "Smart Notepad Application (Notion Clone)",
107 | "summary": "Notion benzeri bir not tutma uygulaması olarak düşünülebilir. Desktop uygulaması stilinde geliştirilebilir. Notion'daki her özelliği içermesine gerek yoktur ancak notları kalıcı olarak saklama, hatırlatma, önceliklendir ve export/import gibi özellikler barındırabilir.",
108 | "level": 70
109 | },
110 | {
111 | "id": "58a3c9a1-e7e5-4b78-b2d8-1e8ea82ac7bf",
112 | "title": "Simple 2D Platform Game",
113 | "summary": "OpenGL veya DirectX gibi kütüphanelere erişebilen paketler ile masaüstü windows uygulaması olarak geliştirilebileceği gibi Unity ile de yazılabilir. Tek sahnelik bir platform oyunu olması yeterlidir.",
114 | "level": 80
115 | },
116 | {
117 | "id": "b496f71f-3f1b-45b9-89cc-6cccf45b307a",
118 | "title": "ECS Based Game Engine",
119 | "summary": "Burada asıl amaç ECS (Entity Component System) yapısını kullanan basit bir oyun motorunun inşasıdır. C# dilinin temel enstrümanları ve .net platformunun bazı özellikleri kullanılarak tasarlanmaya çalışılır.",
120 | "level": 100
121 | }
122 | ]
--------------------------------------------------------------------------------
/Chapter00/Program.cs:
--------------------------------------------------------------------------------
1 | // var trackingSystem = new Homework(); // Default Constructor
2 | var trackingSystem = new Homework(
3 | Guid.NewGuid()
4 | , "Inventory Tracking System"
5 | , "Bu projede amaç basit bir envanter takip sistemi geliştirilmesidir."
6 | , 70);
7 |
8 | Console.WriteLine("{0}", trackingSystem.Title);
9 |
10 | // var apiGateway = new Homework();
11 |
12 | object obj = trackingSystem;
13 |
14 | // trackingSystem.Title="Inventory";
15 |
16 |
17 | List homeworks =
18 | [
19 | trackingSystem,
20 | new Homework(
21 | Guid.NewGuid()
22 | , "Random Data Generator"
23 | , "Rastgele veri oluşturma aracı"
24 | , 90)
25 | ];
26 |
27 | // List homeworks = new List();
28 | // homeworks.Add(trackingSystem);
29 | // homeworks.Add(
30 | // new Homework(
31 | // Guid.NewGuid()
32 | // , "Random Data Generator"
33 | // , "Rastgele veri oluşturma aracı"
34 | // , 90)
35 | // );
36 |
37 | // var randomGenerator = new Homework();
38 | // Console.WriteLine("{0}", randomGenerator);
39 |
40 | // float pi = 3.14F;
41 | // var square= pi *2 *2;
42 |
43 |
44 | // Set Fields
45 | // trackingSystem.Id = Guid.NewGuid();
46 | // trackingSystem.Title = "Inventory Tracking System";
47 | // trackingSystem.Summary = "Bu projede amaç basit bir envanter takip sistemi geliştirilmesidir.";
48 | // trackingSystem.Level = 70;
49 |
50 | // Print Out
51 | // Console.WriteLine("{0} (L:{2})\n\t{1}", trackingSystem.Title, trackingSystem.Summary, trackingSystem.Level);
52 | Console.WriteLine("{0}", trackingSystem);
53 |
54 | // Entity Design
55 | class Homework(Guid id, string title, string summary, short level) // Primary Constructor
56 | {
57 | // Read-only Properties
58 | public Guid Id { get; private set; } = id;
59 | public string Title { get; private set; } = title;
60 | public string Summary { get; private set; } = summary;
61 | public short Level { get; private set; } = level;
62 | // public Homework()
63 | // {
64 |
65 | // }
66 | // public Homework(Guid id, string title, string summary, short level)
67 | // {
68 | // Id = id;
69 | // Title = title;
70 | // Summary = summary;
71 | // Level = level;
72 | // }
73 | public override string ToString()
74 | {
75 | return $"{Id}:{Title}(L:{Level})\n\t{Summary}";
76 | }
77 | }
78 |
79 | // class Homework
80 | // {
81 | // Guid _id;
82 | // public void SetId()
83 | // {
84 | // _id = Guid.NewGuid();
85 | // }
86 | // public Guid Id()
87 | // {
88 | // return _id;
89 | // }
90 | // string? _title;
91 | // public void SetTitle(string title){
92 | // if(string.IsNullOrEmpty(title)) {
93 | // throw new ArgumentException("There is no title");
94 | // }
95 | // _title=title;
96 | // }
97 | // string? Summary;
98 | // short Level;
99 | // public override string ToString()
100 | // {
101 | // return $"{Id}:{Title}(L:{Level})\n\t{Summary}";
102 | // }
103 | // }
104 |
--------------------------------------------------------------------------------
/Chapter01/Chapter01.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Chapter01/Model/Car.cs:
--------------------------------------------------------------------------------
1 | /*
2 | Bütün tip tanımları(class, struct, interface, delegate, enum vs) bir namespace içerisinde yer alır.
3 | Namespace, aynı amaca hizmet eden enstrümanların toplandığı yerdir(Farklı dillerde package, module gibi görebiliriz)
4 | Namespace, kavramsal bir anlam bütünlüğü sağlar.
5 | */
6 | namespace Chapter01.Model
7 | {
8 | internal class Car
9 | {
10 | public string Name;
11 | // Color field'ının string yerine kendi tasarladığımı ProductColor enum sabiti ile de kullanabiliriz
12 | // public string Color;
13 | public ProductColor Color; // Color alanı(field) sadece ProductColor enum sabiti türünden bir değer alabilir
14 | public string Model;
15 | public short Year;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Chapter01/Model/IpInfo.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter01.Model
2 | {
3 | /*
4 | struct ve class arasındaki en temel fark bellekte tutulma biçimidir.
5 | Struct'lar değer türü(Value Type) formatında, kaplayacakları alanlar belli olan türlerdir ve bellekte Stack bölgesinde dururlar.
6 | Class'lar ise referans türü(Reference Type) formatında olup kaplayacakları alan genelde runtime'de belli olan, değişebilen
7 | ve bu sebeplerden belleğin Heap bölgesinde duran enstrümanlardır.
8 | Buna göre birbirleri arasındaki atamalar farklılık gösterebilir.
9 |
10 | Kendi tasarlayacağımız türler class olmak zorunda değildir. Veri içeriğine bunları struct olarak da ele alabiliriz.
11 |
12 | Örneğin IpInfo veri modelinde içerikteki tüm türler byte cinsindendir. Yani herbiri birer Struct'tır. Bellekte kaplayacağı yer bellidir.
13 | Değer türü gibi kullanılabilir bir modeldir.
14 | */
15 | internal struct IpInfo
16 | {
17 | public byte Part1;
18 | public byte Part2;
19 | public byte Part3;
20 | public byte Part4;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Chapter01/Model/ProductColor.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter01.Model
2 | {
3 | /*
4 | Kendi tasarlayabileceğimi türlerden birisi de Enum sabitleridir.
5 | Genellikle sayısal ifadeleri daha okunabilir anlamlı ifadelere eşleştirmek için kullanılır.
6 | enum türleri struct veya class gibi iş yapan fonksiyonlar veya metotlar içermez.
7 |
8 | Sorular :
9 |
10 | - ProductColor enum sabitinde renkler için sayısal değerler kullanılabilir mi?
11 | */
12 | internal enum ProductColor
13 | {
14 | Black,
15 | White,
16 | Green,
17 | Blue,
18 | Yellow
19 | }
20 | /*
21 | Renk gibi bir kavram dahi kullanılacağı yere göre farklı veri türleri şeklinde inşa edilebilir.
22 | Bir grafik programda RGB ayarında kullanılması gerekirken, belki bir e-ticaret sisteminde business anlamda
23 | kullanılan sabit renkleri ifade eden bir enum da olabilir.
24 |
25 | ObjectColor struct'ı da ProductColor.cs gibi ayrı bir dosyaya alınsa iyi olur.
26 |
27 | Sorular :
28 |
29 | - Metinsel bir ifadeden(örneğin hexadecimal bir string değerden, #FFFF00 gibi RGB struct nesnesi elde edilebilir mi?
30 | - Bir ObjectColor nesnesini örneklerken constructor gibi metotlar kullanılabilir mi?
31 | */
32 | internal struct ObjectColor
33 | {
34 | public byte Red;
35 | public byte Green;
36 | public byte Blue;
37 | public byte TransperencyRate;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Chapter01/Program.cs:
--------------------------------------------------------------------------------
1 | /*
2 | Uygulama sınıfımızın adı Program.
3 | Bir tipi başka bir tür içinde(Program sınıfı gibi) kullanırken dahil olduğu namespace bilgisini eklemek gerekebilir.
4 | */
5 | using Chapter01.Model;
6 | // using System.Net;
7 |
8 | internal class Program
9 | {
10 | /*
11 | Executable binary'lerin (Console App, Windows App) ilk giriş noktası Main metodudur
12 | İsterse Main fonksiyonu terminalden ya da başka bir input kaynağında parametre alabilir (args değişkeni)
13 | args değişkeni n adet parametre alabilen bir string dizidir (Array)
14 |
15 | Main metodu genelde bir sonuç döndürmez(istisnai durumlar vardır. Eğer program çıktısı başka bir program veya OS için önemlisi)
16 |
17 | Bir metot geriye birşey döndürmeyecekse void olarak tanımlanır.
18 |
19 | Main metodu varsayılan olarak private erişim belirleyicisine sahiptir. Yani sadee Program sınıfı içinde kullanılabilir.
20 | ve aynı zamanda statik bir metoddur(statik metotlar tanımlandıkları nesnenin örneğine ihtiyaç olmadan kullanılabilirler)
21 | Örneğin Console sınıfının WriteLine metodu statik bir fonksiyondur.
22 |
23 | Sınıflar(Program sınıfı gibi) metotlar(static, constructor, destructor vs), alanlar(fields), özellikler(properties) veya başka türleri de içerebilir.
24 | */
25 | private static void Main(string[] args)
26 | {
27 | Console.Beep();
28 | Console.WriteLine("Hello, World!"); // WriteLine ve Beep, Console sınıfının statik metotlarıdır. Nesne örneğine ihtiyaç duymayan metotalar.
29 |
30 | string fullName = "Burak Selim Şenyurt";
31 | string repoAddress = "https://github.com/buraksenyurt/ProgrammingWithCSharp";
32 | // var keyword ile tanımlanan değişkenler, eşitliğin sağ tarafına bakıp uygun veri türünü alırlar.
33 | // var, eşitliğin sağ tarafı farklı türlere denk geliyorsa varsayılan olanı kullanır
34 | var blogAddress = "buraksenyurt.com";
35 | // Aynı scope içerisinde { } aynı isimde değişkenler tanımlanamaz.
36 | var age = 47;
37 | short level = 101;
38 | byte redValue = 210;
39 | bool isOnline = true;
40 | char flag = 'A';
41 |
42 | double pi = 3.14;
43 | decimal productPrice = 999.45M;
44 | float e = 2.22F;
45 |
46 | /*
47 | .Net platformunda CTS(Common Type System) üzerinden gelen built-in türler dışında,
48 | kendi türlerimizi de tasarlayabiliriz. Bunun için class, struct, enum gibi blokları kullanırız.
49 | */
50 | Car duldul = new Car();
51 | duldul.Name = "Dül Dülüm";
52 | duldul.Year = 1976;
53 | duldul.Model = "Murat 124 AC SLX";
54 | // duldul.Color = "Pamuk helva şekeri rengi";
55 | duldul.Color = ProductColor.Black;
56 | // #FFCC00 (Hexadecimal renk kodu)
57 |
58 | // Aşağıdaki IP adresini string olarak değil de daha kullanışlı olması için bir struct olarak tasarlayalım.
59 | // string localIpAddress = "127.0.0.1";
60 |
61 | // IPAddress (Built-In gelen bu sınıfın içeriğini inceleyelim)
62 |
63 | var printerAddress = new IpInfo
64 | {
65 | Part1 = 192,
66 | Part2 = 168,
67 | Part3 = 1,
68 | Part4 = 1
69 | };
70 | Console.WriteLine("{0}.{1}.{2}.{3}", printerAddress.Part1, printerAddress.Part2, printerAddress.Part3, printerAddress.Part4);
71 | }
72 | }
--------------------------------------------------------------------------------
/Chapter02/Chapter02.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Chapter02/Program.cs:
--------------------------------------------------------------------------------
1 | using Azon.WeatherLib;
2 | using Chapter02.UI.View;
3 |
4 | namespace Chapter02
5 | {
6 | internal class Program
7 | {
8 | static void Main()
9 | {
10 | /*
11 | Temperature veri yapısı Azon.WeatherLib kütüphanesi içinde yer almaktadır.
12 | Temperature sınıfı object instance formasyonunda kullanılır. Yani önce new ile bir örnek oluşturulur.
13 | Sonra bu örneğin erişilebilir olan üyeleri(metotlar gibi) kullanılır.
14 | */
15 | //var currentWeatherValue = new Temperature(21, TemperatureType.Celcius);
16 | //Console.WriteLine(currentWeatherValue);
17 | //currentWeatherValue.ConvertToFahrenheit();
18 | //Console.WriteLine(currentWeatherValue);
19 |
20 | //Terminal.SplashScreen("Super Mario");
21 | //Terminal.ShowMenu();
22 | //Terminal.GetUserInput();
23 |
24 | var reporter = new Reporter();
25 | var ankara = new City("Ankara", new Temperature(14, TemperatureType.Celcius));
26 | reporter.AddCity(ankara);
27 | var tokyo = new City("Tokyo", new Temperature(24, TemperatureType.Celcius));
28 | reporter.AddCity(tokyo);
29 | reporter.AddCity(new City("İstanbul", new Temperature(16, TemperatureType.Celcius)));
30 |
31 | var cities = reporter.GetCityList();
32 | foreach (var city in cities)
33 | {
34 | Console.WriteLine($"City: {city}");
35 | }
36 |
37 | var ankaraTemprature = reporter.GetTemperature("ankara");
38 | Console.WriteLine("{0}", ankaraTemprature);
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Chapter03/Chapter03.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Chapter03/GameWorld.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter03
2 | {
3 | /*
4 | GameObject sınıfımız oyun sahasındaki nesnelerimizin ortak özellik ve fonksiyonlarını sağlayan bir
5 | base tür olarak düşünebiliriz.
6 |
7 | Plane ve Player sınıfları GameObject tipinden türemişlerdir ve bu nedenle X,Y özelliklerine ve Draw metoduna sahiptirler.
8 | Ama aynı zamanda Plane nesnesinin ve Player nesnesinin kendisine has özellik ve metotları vardır.
9 |
10 | C#, sınıflar üzerinden çok kalıtımı(multi-inheritance) desteklemez ancak bu Interface kullanımları ile mümkün olabilir.
11 | */
12 | public class GameObject
13 | {
14 | public int X { get; set; }
15 | public int Y { get; set; }
16 | /*
17 | Draw metodu virtual tanımlanmıştır, varsayılan(default) bir davranışı vardır
18 | ama isterseniz türeyen sınıfta bu davranışı değiştirebilirsiniz(override)
19 | */
20 | public virtual void Draw()
21 | {
22 | Console.WriteLine("Nesne çizdirme operasyonu yapılıyor");
23 | }
24 | }
25 | public class Plane : GameObject
26 | {
27 | public int Alttitude { get; set; }
28 | public double Health { get; set; }
29 | public void Fire()
30 | {
31 | Console.WriteLine("Uçak ateş ediyor");
32 | }
33 | /*
34 | Plane nesnesi için GameObject'te tanımlı Draw metodu ezilmiş ve işleyişi değiştirilmiştir.
35 | */
36 | public override void Draw()
37 | {
38 | Console.WriteLine("Uçak çiziliyor");
39 | }
40 | }
41 | public class Player : GameObject
42 | {
43 | public string Name { get; set; }
44 | public double Power { get; set; }
45 | public void SayGreetings()
46 | {
47 | Console.WriteLine("Oyuncu sizi selamlıyor");
48 | }
49 | public void Jump()
50 | {
51 | Console.WriteLine("Oyuncu zıplıyor");
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Chapter03/HttpManager.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter03
2 | {
3 | /*
4 | HttpManager sınıfının görevi belli url'ler için çeşitli işlemleri gerçekleştirmek olsun.
5 | Örneğin bir web servisine veri göndermek ve cevap almak gibi(Send)
6 | Basit olması açısından sadece string türle çalıştık.
7 | */
8 | public class HttpManager
9 | {
10 | public string Send(string url, string data)
11 | {
12 | Console.WriteLine($"{url} adresine mesaj gönderilecek");
13 |
14 | // Url bilgisi boş veya null ise ya da https:// ile başlamıyorsa ortama exception fırlat
15 | if (string.IsNullOrEmpty(url) || !url.StartsWith("https://"))
16 | {
17 | throw new InvalidUrlException(url);
18 | }
19 | return "Http OK(200)";
20 | }
21 | }
22 |
23 | /*
24 | InvalidUrlException sınıfının bir Exception olarak throw edilebilmesi için
25 | Exception sınıfından türemesi(inherit) yeterlidir. Bu sayede Exception sınıfındaki bazı ortak
26 | özellik ve metotlara da sahip olur. Yani kendi exception nesnelerimiz için sahip olmaları gereken
27 | üyeleri tekrardan yazmak zorunda kalmayız. Bunları base type karşılar.
28 | */
29 | public class InvalidUrlException
30 | : Exception
31 | {
32 | /*
33 | base keyword, bir üst sınıfı işaret eder.
34 | Şu anki senaryoda base ile Exception sınıfı ifade edilir.
35 | constructor' da yaptığımız kullanıma göre base türün yani Exception sınıfının constructor metodu
36 | çağırılır.
37 | */
38 | public InvalidUrlException(string url)
39 | : base($"{url} bilgisi geçersiz.")
40 | {
41 |
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Chapter04/Chapter04.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Chapter04/InterfaceSampleApplication.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter04
2 | {
3 | /*
4 | Türeyen türlerin mutlaka uyması gereken kuralları söylemenin bir diğer yolu da Interface tipinden yararlanmaktır.
5 | Interface türü ile de çok biçimlilik sağlanabilir yani bir interface kendisini uygulayan nesneleri taşıyabilir,
6 | onlara tanımladığı davranışları işletebilir.
7 | */
8 | public abstract class GameObject
9 | {
10 | protected Guid Id { get; private set; }
11 | public Vector2D Position { get; private set; }
12 | protected GameObject(Vector2D position)
13 | {
14 | Id = Guid.NewGuid();
15 | Position = position;
16 | }
17 | void GetSummary()
18 | {
19 | }
20 | }
21 |
22 | /*
23 | abstract türlerden farklı olarak interface tipi sadece davranış tanımlar(Contract)
24 | yani hiçbir şekilde iş yapan kodlar içermez.
25 | IPlayable interface tipi Draw ve Update isimli iki metot tanımlar.
26 | Bu interface türünü uygulayan her tür bu metotları yazmak zorundadır.
27 | Interface türü, SOLID prensiplerinden Depdency Inversion içerisinde de sıklıkla geçer.
28 | Bağımlılıkları tersine çevirmek için kullanılır.
29 | */
30 | interface IPlayable
31 | {
32 | void Draw(); // public, protected, private vb erişim belirleyicileri de(access modifiers) içermez çünkü doğal olarak herkese açıktır
33 | void Update();
34 | }
35 |
36 | /*
37 | Wall sınıf hem bir GameObject türüdür hem de IPlayable davranışlarına sahiptir.
38 | Bir sınıfa birden fazla interface uyarlanabilir ama birden fazla sınıftan türetilemez.
39 | */
40 | public class Player
41 | : GameObject, IPlayable
42 | {
43 | public string Name { get; set; }
44 | public Player(Vector2D position)
45 | : base(position)
46 | {
47 | }
48 | public void Draw()
49 | {
50 | Console.WriteLine($"{Id} player - is drawing...");
51 | }
52 |
53 | public void Update()
54 | {
55 | Console.WriteLine($"{Id} player - is updating...");
56 | }
57 | }
58 |
59 | public class Tower
60 | : GameObject, IPlayable
61 | {
62 | public int Health { get; set; }
63 | public Tower(Vector2D position)
64 | : base(position)
65 | {
66 | }
67 | public void Draw()
68 | {
69 | Console.WriteLine($"{Id} tower - is drawing...");
70 | }
71 |
72 | public void Update()
73 | {
74 | Console.WriteLine($"{Id} tower - is updating...");
75 | }
76 | }
77 |
78 | public class Wall
79 | : IPlayable
80 | {
81 | public string Color { get; set; }
82 | public void Draw()
83 | {
84 | Console.WriteLine($"Wall is drawing...");
85 | }
86 |
87 | public void Update()
88 | {
89 | Console.WriteLine($"Wall is updating...");
90 | }
91 | }
92 |
93 | public class Engine
94 | {
95 | private readonly List playables = [];
96 |
97 | // Bu fonksiyon aslında oyun motorunda olmaz(Eğitimde sadece simülasyon için kullandık)
98 | public void LoadLevel(string level)
99 | {
100 | Console.WriteLine($"{level} içeriği yükleniyor");
101 |
102 | playables.Add(new Tower(new Vector2D { X = 10, Y = 4 }) { Health = 100 });
103 | playables.Add(new Player(new Vector2D { X = 5, Y = 5 }) { Name = "Prince of Persia" });
104 | playables.Add(new Wall() { Color = "Black" });
105 | playables.Add(new Wall() { Color = "Red" });
106 | }
107 | public void Run()
108 | {
109 | /*
110 | Abstract sınıflarda olduğu interface tipleri de new operatörü örneklenemez
111 | Hatta interface tamamen polimorfik(bukalemun) bir türdür. Kendisinde tanımlanan davranışları yazmış nesneler gibi hareket eder
112 |
113 | Aşağıdaki döngüde GameEngine nesnesindeki playables isimli List koleksiyonu dönülürken,
114 | playable değişkenine hangi türeyen nesne gelirse onun Update ve Draw metotları çağrılır.
115 | */
116 |
117 | foreach (IPlayable playable in playables)
118 | {
119 | playable.Update();
120 | playable.Draw();
121 | }
122 | }
123 | }
124 |
125 | public static class InterfaceSampleApplication
126 | {
127 | public static void Run()
128 | {
129 | var gameEngine = new Engine();
130 | gameEngine.LoadLevel("Beginner");
131 | gameEngine.Run();
132 | }
133 | }
134 | }
--------------------------------------------------------------------------------
/Chapter04/InterfaceSeperation.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter04
2 | {
3 | /*
4 | Sonraki derste bu konu üzerinde tekrar duracağız.
5 | */
6 | public interface IDrawable
7 | {
8 | void Draw();
9 | }
10 |
11 | public interface IUpdatable
12 | {
13 | void Update();
14 | }
15 | public class Enemy : IUpdatable, IDrawable
16 | {
17 | public void Draw()
18 | {
19 | throw new NotImplementedException();
20 | }
21 |
22 | public void Update()
23 | {
24 | throw new NotImplementedException();
25 | }
26 | }
27 | public class Tile : IDrawable
28 | {
29 | public void Draw()
30 | {
31 | throw new NotImplementedException();
32 | }
33 | }
34 | public class Score : IUpdatable
35 | {
36 | public void Update()
37 | {
38 | throw new NotImplementedException();
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Chapter04/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter04
2 | {
3 | internal class Program
4 | {
5 | static void Main(string[] args)
6 | {
7 | // AbstractSampleApplication.Run();
8 | InterfaceSampleApplication.Run();
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Chapter05/Chapter05.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Chapter05/Components/Button.cs:
--------------------------------------------------------------------------------
1 | using Chapter05.Contracts;
2 |
3 | namespace Chapter05.Components;
4 |
5 | public class Button(int id, string name, (double, double) position)
6 | : ButtonBase(id, name, position), IDrawable
7 | {
8 | protected bool IsCorneredCurve { get; set; }
9 | public string? Text { get; set; }
10 |
11 | public void Draw()
12 | {
13 | Console.WriteLine("Button draw at {0}:{1}", Position.Item1, Position.Item2);
14 | }
15 | public override string ToString()
16 | {
17 | return $"{base.ToString()}|{Text}|{IsCorneredCurve}";
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Chapter05/Components/ButtonBase.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter05.Components;
2 |
3 | /*
4 | Control sınıfından türeyen ButtonBase, Button türevli bileşenleri ifade eder.
5 | Tüm Button'lar için ortak olabilecek bazı özellikleri veya metotları içerebilir.
6 | */
7 | public abstract class ButtonBase(int id, string name, (double, double) position)
8 | : Control(id, name, position)
9 | {
10 | /*
11 | Aslında arka plan ve ön plan rengi ve hatta yazının büyüklüğü, türü, yatık olması vs
12 | gibi unsular FontStyle gibi farklı bir sınıfın özellikleri olabilir.
13 | */
14 | public string? BackgroundColor { get; set; }
15 | public string? ForegroundColor { get; set; }
16 | }
17 |
--------------------------------------------------------------------------------
/Chapter05/Components/CheckBox.cs:
--------------------------------------------------------------------------------
1 | using Chapter05.Contracts;
2 |
3 | namespace Chapter05.Components;
4 |
5 | public class CheckBox(int id, string name, (double, double) position)
6 | : Control(id, name, position), IDrawable
7 | {
8 | public string? Text { get; set; }
9 | public bool IsChecked { get; set; }
10 |
11 | public void Draw()
12 | {
13 | Console.WriteLine("CheckBox draw at {0}:{1}", Position.Item1, Position.Item2);
14 | }
15 | public override string ToString()
16 | {
17 | return $"{base.ToString()}|{Text}|{IsChecked}";
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Chapter05/Components/Control.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter05.Components;
2 |
3 | /*
4 | Tasarımımıza göre ekrana çizilebilen tüm bileşenleri tarifleyen nesnedir.
5 | */
6 | public abstract class Control(int id, string name, (double, double) position)
7 | {
8 | public int Id { get; set; } = id;
9 | protected string? Name { get; set; } = name;
10 | protected (double, double) Position { get; set; } = position;
11 |
12 | public override string ToString()
13 | {
14 | return $"{Id}|{this.GetType().Name}|{Name}|{Position}";
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Chapter05/Components/DbConnector.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter05.Components;
2 |
3 | /*
4 | DbConnector sınıfının en büyük özelliği bir Control olması ama Draw metodunu içermemesidir.
5 | Tasarımımıza göre her kontrol Container nesne içerisinde çizilebilir olacak diye bir kural yoktur.
6 | */
7 | public class DbConnector(int id, string name, (double, double) position)
8 | : Control(id, name, position)
9 | {
10 | public string? ConnectionString { get; set; }
11 |
12 | public override string ToString()
13 | {
14 | return $"{base.ToString()}|{ConnectionString}";
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Chapter05/Components/GridBox.cs:
--------------------------------------------------------------------------------
1 | using Chapter05.Contracts;
2 |
3 | namespace Chapter05.Components;
4 |
5 | internal class GridBox(int id, string name, (double, double) position)
6 | : Control(id, name, position), IDrawable
7 | {
8 | public int RowCount { get; set; }
9 | public int ColumnCount { get; set; }
10 |
11 | public void Draw()
12 | {
13 | Console.WriteLine("GridBox draw at {0}:{1}", Position.Item1, Position.Item2);
14 | }
15 | public override string ToString()
16 | {
17 | return $"{base.ToString()}|{RowCount}|{ColumnCount}";
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Chapter05/Components/Label.cs:
--------------------------------------------------------------------------------
1 | using Chapter05.Contracts;
2 |
3 | namespace Chapter05.Components;
4 |
5 | public class Label(int id, string name, (double, double) position)
6 | : Control(id, name, position), IDrawable
7 | {
8 | public string Text { get; set; }
9 |
10 | public void Draw()
11 | {
12 | Console.WriteLine("Label draw at {0}:{1}", Position.Item1, Position.Item2);
13 | }
14 | public override string ToString()
15 | {
16 | return $"{base.ToString()}|{Text}";
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Chapter05/Components/LinkButton.cs:
--------------------------------------------------------------------------------
1 | using Chapter05.Contracts;
2 |
3 | namespace Chapter05.Components;
4 |
5 | public class LinkButton(int id, string name, (double, double) position)
6 | : ButtonBase(id, name, position), IDrawable
7 | {
8 | public Uri Url { get; set; }
9 |
10 | public void Draw()
11 | {
12 | Console.WriteLine("LinkButton draw at {0}:{1}", Position.Item1, Position.Item2);
13 | }
14 | public override string ToString()
15 | {
16 | return $"{base.ToString()}|{Url}";
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Chapter05/Components/RadioButton.cs:
--------------------------------------------------------------------------------
1 | using Chapter05.Contracts;
2 |
3 | namespace Chapter05.Components;
4 |
5 | public class RadioButton(int id, string name, (double, double) position)
6 | : ButtonBase(id, name, position), IDrawable
7 | {
8 | public List Options { get; set; } = [];
9 | public string SelectedOption { get; set; }
10 |
11 | public void Draw()
12 | {
13 | Console.WriteLine("RadioButton draw at {0}:{1}", Position.Item1, Position.Item2);
14 | }
15 | public override string ToString()
16 | {
17 | return $"{base.ToString()}|{SelectedOption}";
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Chapter05/Containers/Form.cs:
--------------------------------------------------------------------------------
1 | using Chapter05.Components;
2 | using Chapter05.Contracts;
3 |
4 | namespace Chapter05.Containers;
5 |
6 | /*
7 | Form sınıfı bizim için bir Container görevi görüyor.
8 | Kendi içinde Control türünden herhangibir nesne listesini barındırabilir.
9 | Bu nesneler için toplu çizim, ekran yerleşimi, kaydetme veya yükleme(load) işlemlerini icra edebilir.
10 | */
11 | public class Form(IPersistence persistence)
12 | {
13 | private readonly List _controls = [];
14 |
15 | /*
16 | Form nesnesi kaydetme işlemi IPersistence arayüzünü implemente eden bileşenleri kullanır.
17 | Bunu constructor üzerinden parametre ile verebiliriz. Buna Constructor Injection denir.
18 | */
19 | private readonly IPersistence _persistence = persistence;
20 |
21 | public void AddControls(params Control[] controls)
22 | {
23 | _controls.AddRange(controls);
24 | }
25 | public void LocateAll()
26 | {
27 | foreach (Control control in _controls)
28 | {
29 | Console.WriteLine($"{control.Id} location set");
30 | }
31 | }
32 | public void DrawAll()
33 | {
34 | /*
35 | DrawAll metodu Control türünden tüm nesne örneklerini dolaşır ama bunlardan
36 | sadece IDrawable interface' ini implemente etmiş olanların kullanılması gerekir.
37 | Bunun için is operatörü ile o anki nesnenin IDrawable olup olmadığına (ya da) Draw
38 | davranışına sahip olup olmadığına bakılır.
39 | */
40 | foreach (Control control in _controls)
41 | {
42 | if (control is IDrawable drawable)
43 | {
44 | drawable.Draw();
45 | }
46 | }
47 | }
48 |
49 | public void Save()
50 | {
51 | /*
52 | Save metodu aslında IPersistence arayüzü üzerinden atanan bileşen kimse
53 | onun Save metodunu, bu sınıfın Controls listesi için çalıştırır.
54 | */
55 | _persistence.Save(_controls);
56 | }
57 |
58 | /*
59 | Save metodu aşağıdaki versiyon itibariyle tüm veri içeriğini tasarlandığı gibi
60 | Form.dat isimli bir dosyaya kaydeder.
61 | Peki farklı formatta kaydetmek istersem ya da başka bir yere
62 | (Database, Cloud üzerinde bir servis vb)
63 | ne yapmam gerekir?
64 |
65 | Buradaki düşünce yapımız temelde şu, Form sınıfını değiştirmeden kaydetme işini üstlenen
66 | bir başka component'i kullanmasını sağlamak ve bu şekilde genişletmek.
67 | Kod değiştirilmeye kapalı, genişletilmeye açık.
68 |
69 | Burada Dependency Inversion prensibinden yararlanabiliriz.
70 | */
71 | //public void Save(string FileType)
72 | //{
73 | // /*
74 | // Id|Control Type|Name|X Position|Y Position|Other Control Properties|
75 |
76 | // 1|Button|btnSave|10|20|Save
77 | // 2|Button|btnClose||100|20|Is Active Profile
78 | // 3|LinkButton|lnkAbout|50|20|About
79 | // 4|CheckBoxButton|10|10|Is Active Profile
80 | // */
81 |
82 | // if (FileType == "csv")
83 | // {
84 |
85 | // var builder = new StringBuilder();
86 | // foreach (Control control in _controls)
87 | // {
88 | // builder.AppendLine(control.ToString());
89 | // }
90 | // var content = builder.ToString();
91 | // File.WriteAllText("Form.dat", content);
92 | // }
93 | // else if (FileType == "json")
94 | // {
95 | // // JSON formatında kaydetme işlemi
96 | // }
97 | // else if (FileType == "database")
98 | // {
99 | // // Database'e kaydetme işlemi
100 | // } else if (FileType == "cloud")
101 | // {
102 |
103 | // }
104 | //}
105 | }
106 |
--------------------------------------------------------------------------------
/Chapter05/Contracts/IDrawable.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter05.Contracts;
2 |
3 | public interface IDrawable
4 | {
5 | void Draw();
6 | }
7 |
--------------------------------------------------------------------------------
/Chapter05/Contracts/IPersistence.cs:
--------------------------------------------------------------------------------
1 | using Chapter05.Components;
2 |
3 | namespace Chapter05.Contracts;
4 |
5 | public interface IPersistence
6 | {
7 | void Save(List controls);
8 | }
9 |
--------------------------------------------------------------------------------
/Chapter05/Persistence/CsvPersistence.cs:
--------------------------------------------------------------------------------
1 | using Chapter05.Components;
2 | using Chapter05.Contracts;
3 | using System.Text;
4 |
5 | namespace Chapter05.Persistence;
6 |
7 | public class CsvPersistence
8 | : IPersistence
9 | {
10 | public string FilePath { get; set; } = Path.Combine(Environment.CurrentDirectory, "Form.dat");
11 | public void Save(List controls)
12 | {
13 | var builder = new StringBuilder();
14 | foreach (Control control in controls)
15 | {
16 | builder.AppendLine(control.ToString());
17 | }
18 | var content = builder.ToString();
19 | File.WriteAllText(FilePath, content);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Chapter05/Persistence/DbPersistence.cs:
--------------------------------------------------------------------------------
1 | using Chapter05.Components;
2 | using Chapter05.Contracts;
3 |
4 | namespace Chapter05.Persistence;
5 |
6 | public class DbPersistence
7 | : IPersistence
8 | {
9 | public void Save(List controls)
10 | {
11 | Console.WriteLine("Database save");
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Chapter05/Program.cs:
--------------------------------------------------------------------------------
1 | using Chapter05.Components;
2 | using Chapter05.Containers;
3 | using Chapter05.Persistence;
4 |
5 | namespace Chapter05;
6 |
7 | internal class Program
8 | {
9 | static void Main()
10 | {
11 | var csvSaver = new CsvPersistence();
12 |
13 | // var dbSaver = new DbPersistence();
14 | Form mainForm = new(csvSaver);
15 |
16 | Button btnSave = new(101, "btnSave", (0, 100))
17 | {
18 | Text = "Save"
19 | };
20 | Button btnClose = new(102, "btnClose", (0, 500))
21 | {
22 | Text = "Close"
23 | };
24 | CheckBox chkIsActiveProfile = new(104, "chkIsActive", (0, 10))
25 | {
26 | Text = "Is Active Profile",
27 | IsChecked = true
28 | };
29 | Label lblTitle = new(106, "lblTitle", (50, 50))
30 | {
31 | Text = "Title"
32 | };
33 | LinkButton lnkAbout = new(204, "lnkAbout", (400, 50))
34 | {
35 | Url = new Uri("https://www.azon.com.tr/about")
36 | };
37 | DbConnector dbConnector = new(90, "dbConnector", (0, 0))
38 | {
39 | ConnectionString = "data source=localhost:database=Northwind;integrated security=sspi"
40 | };
41 |
42 | mainForm.AddControls(btnSave, btnClose, lblTitle, lnkAbout, chkIsActiveProfile, dbConnector);
43 | mainForm.DrawAll();
44 | mainForm.Save();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Chapter06/Chapter06.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Chapter06/Dto/ButtonBaseDto.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter06.Dto;
2 |
3 | public class ButtonBaseDto : ControlDto
4 | {
5 | public string? BackgroundColor { get; set; }
6 | public string? ForegroundColor { get; set; }
7 | }
8 |
--------------------------------------------------------------------------------
/Chapter06/Dto/ButtonDto.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter06.Dto;
2 |
3 | public class ButtonDto : ButtonBaseDto
4 | {
5 | public bool IsCorneredCurve { get; set; }
6 | public string? Text { get; set; }
7 | }
8 |
--------------------------------------------------------------------------------
/Chapter06/Dto/CheckBoxDto.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter06.Dto;
2 |
3 | public class CheckBoxDto : ControlDto
4 | {
5 | public string? Text { get; set; }
6 | public bool IsChecked { get; set; }
7 | }
8 |
--------------------------------------------------------------------------------
/Chapter06/Dto/ControlDto.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter06.Dto;
2 |
3 | public class ControlDto
4 | {
5 | public int Id { get; set; }
6 | public string? Name { get; set; }
7 | public (double, double) Position { get; set; }
8 | }
9 |
--------------------------------------------------------------------------------
/Chapter06/Dto/DbConnectorDto.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter06.Dto;
2 |
3 | public class DbConnectorDto : ControlDto
4 | {
5 | public string? ConnectionString { get; set; }
6 | }
7 |
--------------------------------------------------------------------------------
/Chapter06/Dto/GridBoxDto.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter06.Dto;
2 |
3 | public class GridBoxDto : ControlDto
4 | {
5 | public int RowCount { get; set; }
6 | public int ColumnCount { get; set; }
7 | }
8 |
--------------------------------------------------------------------------------
/Chapter06/Dto/LabelDto.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter06.Dto;
2 |
3 | public class LabelDto : ControlDto
4 | {
5 | public string Text { get; set; } = string.Empty;
6 | }
7 |
--------------------------------------------------------------------------------
/Chapter06/Dto/LinkButtonDto.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter06.Dto;
2 |
3 | public class LinkButtonDto : ButtonBaseDto
4 | {
5 | public Uri Url { get; set; } = new Uri("http://localhost");
6 | }
7 |
--------------------------------------------------------------------------------
/Chapter06/Dto/PictureBoxDto.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter06.Dto;
2 |
3 | public class PictureBoxDto : ControlDto
4 | {
5 | public string ImagePath { get; set; }
6 | public int Width { get; set; }
7 | public int Height { get; set; }
8 | }
9 |
--------------------------------------------------------------------------------
/Chapter06/Dto/RadioButtonDto.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter06.Dto;
2 |
3 | public class RadioButtonDto : ButtonBaseDto
4 | {
5 | public List Options { get; set; } = [];
6 | public string SelectedOption { get; set; } = string.Empty;
7 | }
8 |
--------------------------------------------------------------------------------
/Chapter06/Persistence/ControlMapper.cs:
--------------------------------------------------------------------------------
1 | using Azon.Web.Sdk.Components;
2 | using Chapter06.Dto;
3 | using System.Reflection;
4 |
5 | namespace Chapter06.Persistence;
6 |
7 | public static class ControlMapper
8 | {
9 | public static ControlDto ToDto(Control control)
10 | {
11 | return control switch
12 | {
13 | Button button => new ButtonDto
14 | {
15 | Id = button.Id,
16 | Name = GetProtectedProperty(button, "Name"),
17 | Position = GetProtectedProperty(button, "Position"),
18 | BackgroundColor = button.BackgroundColor,
19 | ForegroundColor = button.ForegroundColor,
20 | IsCorneredCurve = button.IsCorneredCurve,
21 | Text = button.Text
22 | },
23 | CheckBox checkBox => new CheckBoxDto
24 | {
25 | Id = checkBox.Id,
26 | Name = GetProtectedProperty(checkBox, "Name"),
27 | Position = GetProtectedProperty(checkBox, "Position"),
28 | Text = checkBox.Text,
29 | IsChecked = checkBox.IsChecked
30 | },
31 | Label label => new LabelDto
32 | {
33 | Id = label.Id,
34 | Name = GetProtectedProperty(label, "Name"),
35 | Position = GetProtectedProperty(label, "Position"),
36 | Text = label.Text
37 | },
38 | LinkButton linkButton => new LinkButtonDto
39 | {
40 | Id = linkButton.Id,
41 | Name = GetProtectedProperty(linkButton, "Name"),
42 | Position = GetProtectedProperty(linkButton, "Position"),
43 | BackgroundColor = linkButton.BackgroundColor,
44 | ForegroundColor = linkButton.ForegroundColor,
45 | Url = linkButton.Url
46 | },
47 | DbConnector dbConnector => new DbConnectorDto
48 | {
49 | Id = dbConnector.Id,
50 | Name = GetProtectedProperty(dbConnector, "Name"),
51 | Position = GetProtectedProperty(dbConnector, "Position"),
52 | ConnectionString = dbConnector.ConnectionString
53 | },
54 | PictureBox pictureBox => new PictureBoxDto
55 | {
56 | ImagePath = pictureBox.ImagePath,
57 | Height = pictureBox.Height,
58 | Width = pictureBox.Width
59 | },
60 | _ => throw new NotSupportedException($"Control type {control.GetType().Name} is not supported.")
61 | };
62 | }
63 |
64 | public static Control FromDto(ControlDto dto)
65 | {
66 | return dto switch
67 | {
68 | ButtonDto buttonDto => new Button(buttonDto.Id, buttonDto.Name!, buttonDto.Position)
69 | {
70 | BackgroundColor = buttonDto.BackgroundColor,
71 | ForegroundColor = buttonDto.ForegroundColor,
72 | Text = buttonDto.Text,
73 | IsCorneredCurve = buttonDto.IsCorneredCurve,
74 | },
75 | CheckBoxDto checkBoxDto => new CheckBox(checkBoxDto.Id, checkBoxDto.Name!, checkBoxDto.Position)
76 | {
77 | Text = checkBoxDto.Text,
78 | IsChecked = checkBoxDto.IsChecked
79 | },
80 | LabelDto labelDto => new Label(labelDto.Id, labelDto.Name!, labelDto.Position)
81 | {
82 | Text = labelDto.Text
83 | },
84 | LinkButtonDto linkButtonDto => new LinkButton(linkButtonDto.Id, linkButtonDto.Name!, linkButtonDto.Position)
85 | {
86 | BackgroundColor = linkButtonDto.BackgroundColor,
87 | ForegroundColor = linkButtonDto.ForegroundColor,
88 | Url = linkButtonDto.Url
89 | },
90 | DbConnectorDto dbConnectorDto => new DbConnector(dbConnectorDto.Id, dbConnectorDto.Name!, dbConnectorDto.Position)
91 | {
92 | ConnectionString = dbConnectorDto.ConnectionString
93 | },
94 | PictureBoxDto pictureBoxDto => new PictureBox(pictureBoxDto.Id, pictureBoxDto.Name!, pictureBoxDto.Position)
95 | {
96 | ImagePath = pictureBoxDto.ImagePath,
97 | Width = pictureBoxDto.Width,
98 | Height = pictureBoxDto.Height
99 | },
100 | _ => throw new NotSupportedException($"DTO type {dto.GetType().Name} is not supported.")
101 | };
102 | }
103 |
104 | private static TProperty GetProtectedProperty(T instance, string propertyName)
105 | {
106 | var propertyInfo = typeof(T).GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance);
107 | if (propertyInfo == null)
108 | {
109 | throw new InvalidOperationException($"Property {propertyName} not found on type {typeof(T).Name}");
110 | }
111 | return (TProperty)propertyInfo.GetValue(instance);
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/Chapter06/Persistence/JsonPersistence.cs:
--------------------------------------------------------------------------------
1 | using Azon.Web.Sdk.Components;
2 | using Azon.Web.Sdk.Contracts;
3 | using Newtonsoft.Json;
4 |
5 | namespace Chapter06.Persistence;
6 |
7 | public class JsonPersistence
8 | : IFilePersistence
9 | {
10 | public string FilePath { get; set; } = Path.Combine(Environment.CurrentDirectory, "Form.json");
11 |
12 | public void Save(List controls)
13 | {
14 | var dtos = controls.Select(ControlMapper.ToDto).ToList();
15 |
16 | var json = JsonConvert.SerializeObject(dtos, Formatting.Indented, new JsonSerializerSettings
17 | {
18 | TypeNameHandling = TypeNameHandling.All
19 | });
20 |
21 | File.WriteAllText(FilePath, json);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Chapter06/PictureBox.cs:
--------------------------------------------------------------------------------
1 | using Azon.Web.Sdk.Components;
2 | using Azon.Web.Sdk.Contracts;
3 |
4 | namespace Chapter06;
5 |
6 | public class PictureBox
7 | : Control, IDrawable
8 | {
9 | public string ImagePath { get; set; }
10 | public int Width { get; set; }
11 | public int Height { get; set; }
12 | public PictureBox(int id, string name, (double, double) position)
13 | : base(id, name, position)
14 | {
15 | }
16 |
17 | public void Draw()
18 | {
19 | Console.WriteLine("PictureBox draw");
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Chapter06/Program.cs:
--------------------------------------------------------------------------------
1 | using Azon.Web.Sdk.Components;
2 | using Chapter06.Persistence;
3 |
4 | namespace Chapter06;
5 |
6 | /*
7 | Bu proje Azon.Web.Sdk ve Azon.Web.Persistence projelerini referans edip kullanmaktadır.
8 | Sdk veya Persistence projelerinde bir değişiklik yapmadan yeni component'ler veya Persistence bileşenleri
9 | Chapter06 runtime'ına eklenebilir. Nitekim, Sdk projesi yeni form bileşeni oluşturmak veya Persistence
10 | bileşeni eklemek için gerekli olan Contract'ları (interface tanımlamaları) sağlar.
11 | */
12 | internal class Program
13 | {
14 | static void Main()
15 | {
16 | // var csvSaver = new CsvPersistence();
17 | var jsonSaver = new JsonPersistence(); // Bu runtime için eklediğimiz kendi Persistence bileşenimiz
18 | Form mainForm = new(jsonSaver);
19 |
20 | // Bu runtime için eklediğimiz kendi Control türevli nesnemiz
21 | PictureBox pictureBox = new(98, "pbProfilePhoto", (0, 0))
22 | {
23 | ImagePath = "profilePhoto.png",
24 | Width = 64,
25 | Height = 64,
26 | };
27 | Button btnSave = new(101, "btnSave", (0, 100))
28 | {
29 | Text = "Save"
30 | };
31 | Button btnClose = new(102, "btnClose", (0, 500))
32 | {
33 | Text = "Close"
34 | };
35 | CheckBox chkIsActiveProfile = new(104, "chkIsActive", (0, 10))
36 | {
37 | Text = "Is Active Profile",
38 | IsChecked = true
39 | };
40 | Label lblTitle = new(106, "lblTitle", (50, 50))
41 | {
42 | Text = "Title"
43 | };
44 | LinkButton lnkAbout = new(204, "lnkAbout", (400, 50))
45 | {
46 | Url = new Uri("https://www.azon.com.tr/about")
47 | };
48 | DbConnector dbConnector = new(90, "dbConnector", (0, 0))
49 | {
50 | ConnectionString = "data source=localhost:database=Northwind;integrated security=sspi"
51 | };
52 |
53 | mainForm.AddControls(btnSave, btnClose, lblTitle, lnkAbout, chkIsActiveProfile, dbConnector, pictureBox);
54 | mainForm.DrawAll();
55 | mainForm.Save();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Chapter08/Chapter08.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Chapter08/Program.cs:
--------------------------------------------------------------------------------
1 | using Azon.Games;
2 |
3 | namespace Chapter08;
4 |
5 | internal class Program
6 | {
7 | static void Main()
8 | {
9 | var catalog = new Catalog();
10 | var games = catalog.LoadGames();
11 |
12 | Console.WriteLine("10 yaşından büyük oyunlar");
13 |
14 | // Aşağıdaki Search kullanımlarında dikkat edileceği üzere ikinci parametre bir fonksiyondur
15 | var resultSet = Scenario01.Search(games, IsOldThen10Age);
16 | resultSet = Scenario01.Search(games, IsStrategyGame);
17 | resultSet = Scenario01.Search(games, IsUnderrated);
18 |
19 | /*
20 | Aşağıdaki gibi, isimsiz metotlar(Anonymous Method) veya farklı dillerde Closure olarak da geçen
21 | kod bloklarını da parametre olarak geçebiliriz.
22 | */
23 | resultSet = Scenario01.Search(games, g => !g.OnSale);
24 |
25 | /*
26 | Koleksiyon türlerine eklenmiş farklı türden delegate tipleri kullanan metotlar vardır.
27 | Örneğin List türünün FindAll metodu, Predicate temsilcisini kullanır.
28 |
29 | public delegate bool Predicate(T obj);
30 |
31 | Bu generic bir tanımlamadır dolayısıyla herhangibir nesne türünü parametre olarak alan
32 | ve geriye bool döndüren metotlar ifade edilebilir.
33 | Aşağıda lambda operatörü (=>) ile bool değer dönen bir ifade FindAll metoduna parametre olarak geçilir.
34 | */
35 | resultSet = games.FindAll(g => g.ListPrice > 30);
36 |
37 | /*
38 | Delegate tipinin yoğun olarak kullanıldığı bir diğer yerde LINQ ifadeleridir.
39 |
40 | LINQ = Language INtegrated Query
41 |
42 | Where, OrderBy, Select gibi genişletme metotları(Extension Methods) vardır. Bunlar genellikle Func türünden
43 | temsilci(delegate) tipleri ile çalışır.
44 | Select metodunun kullanımında dikkat edilmesi gereken noktalardan birisi Id, Title ve UserRate dönen bir nesne tanımlandığıdır.
45 | Bu anonymous type(isimsiz tip) olarak geçer. Zira herhangi bir yerde bu tür için bir sınıf veya struct tanımı yapılmamıştır.
46 | Buradaki isimsiz tip kullanımı Projection olarak da geçer.
47 | */
48 | var queryResult = games
49 | .Where(g => g.Name.ToLower().StartsWith("w"))
50 | .OrderBy(g => g.UserRate)
51 | .Select(g => new
52 | {
53 | g.Id,
54 | Title = g.Name,
55 | g.UserRate
56 | })
57 | .ToList();
58 | foreach (var item in queryResult)
59 | {
60 | Console.WriteLine(item);
61 | }
62 |
63 | /*
64 | Yukarıdaki genişletme metotlarının yerine aşağıdaki gibi SQL sorgularına benzer
65 | şekilde syntax' da mümkündür.
66 |
67 | Burada genel amaça programatik ortamda SQL tarzı sorguların yazılabilmesini sağlamaktır.
68 | LINQ, özellikle O/RM (Object Relational Mapping) konusu için getirilmiştir.
69 | Amaç database tarafındaki tablolar üzerinde yazılan sorguların karşılığı olan entity nesnelerine ait koleksiyonlarda da
70 | benzer şekilde yazılabilmesinin sağlanmasıdır.
71 |
72 | SELECT * FROM Games WHERE ReleaseYear > 1990 AND ReleaseYear < 2000 Order By UserRate DESC
73 | */
74 | var queryResult2 = from g in games
75 | where g.ReleaseYear > 1990 && g.ReleaseYear < 2000
76 | orderby g.UserRate descending
77 | select g;
78 | foreach (var item in queryResult2)
79 | {
80 | Console.WriteLine($"{item.Name}, ({item.UserRate})");
81 | }
82 |
83 | // Category bazlı oyunların ortalama UserRate değeri ?
84 |
85 | /*
86 | Örnek Extension method kullanımı
87 | */
88 | string motto = "Ne kadar güzel bir gün değil mi?";
89 | Console.WriteLine(motto.WriteSmart('_'));
90 | Console.WriteLine(motto.WriteSmart('*'));
91 |
92 | }
93 | static bool IsOldThen10Age(Game game)
94 | {
95 | return DateTime.Now.Year - game.ReleaseYear > 10;
96 | }
97 | static bool IsStrategyGame(Game game)
98 | {
99 | return game.Category.Name.ToLower().Contains("strategy");
100 | }
101 | static bool IsUnderrated(Game game)
102 | {
103 | return game.UserRate < 6;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/Chapter08/Scenario00.cs:
--------------------------------------------------------------------------------
1 | using Azon.Games;
2 |
3 | namespace Chapter08;
4 |
5 | public static class Scenario00
6 | {
7 | /*
8 | games isimli Game türünden olan listede çeşitli aramalar yapmak istediğimizde
9 | ilk akla gelen yollardan birisi aşağıdaki gibi for döngülerini kullanmaktır.
10 | Ancak hemen hepsi sadece koşul dışında aynı şekilde yazılır.
11 |
12 | Tek bir for döngüsü ile herhangibir karşılaştırma kriterini ele alan bir metot yazılabilir mi?
13 | */
14 | public static void Run(List games)
15 | {
16 | // Şu anda satışa olmayan oyunların listesi
17 | Console.WriteLine("Satışta olmayan oyunlar");
18 | foreach (var game in games)
19 | {
20 | if (!game.OnSale)
21 | {
22 | Console.WriteLine($"{game.Name}");
23 | }
24 | }
25 |
26 | Console.WriteLine("\nStrateji Kategorisindeki Oyunlar");
27 | foreach (var game in games)
28 | {
29 | if (game.Category.Name.ToLower().Contains("strategy"))
30 | {
31 | Console.WriteLine($"{game.Name} ({game.UserRate})");
32 | }
33 | }
34 |
35 | // 10 yıldan yaşlı oyunlar
36 | Console.WriteLine("\nOn yıldan yaşlı olan oyunlar");
37 | foreach (var game in games)
38 | {
39 | if (DateTime.Now.Year - game.ReleaseYear > 10)
40 | {
41 | Console.WriteLine($"{game.Name} ({game.UserRate}), {game.ReleaseYear}");
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Chapter08/Scenario01.cs:
--------------------------------------------------------------------------------
1 | using Azon.Games;
2 |
3 | namespace Chapter08;
4 |
5 | // Burada Game türünden parametre alan ve geriye bool değer döndüren metotları işaret edebilen bir temsilci tanımı yapılmıştır
6 | public delegate bool PredicateDelegate(Game game);
7 |
8 | public static class Scenario01
9 | {
10 | /*
11 | Aşağıdaki fonksiyonlar bir oyun nesnesini alıp belli bir kritere uyup uymadığını bulan metotlardır.
12 | Hep Game türünden bir parametre alırlar ve sadece bool değer dönerler(Tümün ortak özellikleri)
13 |
14 | .Net tarafında metotların bellek adresleri delegate tipi(type) ile işaret edilebilir(Method Pointer)
15 | Buna göre bir metodu değişken gibi kullanmak, başka bir metoda parametre olarak geçmek mümkün hale gelir.
16 |
17 | Delegate tipi herhangibir metodu işaret edebilir. Senaryoya göre dönüş türü veya parametre yapısı organize edilir.
18 | */
19 | public static List Search(List games,PredicateDelegate predicate)
20 | {
21 | var result = new List();
22 |
23 | foreach (var game in games)
24 | {
25 | /*
26 | Search metoduna gelen Predicate temsilcisinin işaret ettiği metot kimse
27 | o metot foreach döngüsünün o anki game nesne örneği ile çalıştırılır.
28 | Predicate temsilcisi geriye bool değer döndüğünde kriter sağlanmışsa result'a eklenir
29 | */
30 | if (predicate(game))
31 | {
32 | result.Add(game);
33 | }
34 | }
35 |
36 | return result;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Chapter08/StingExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter08;
2 |
3 | /*
4 | LINQ sorgularında yer alan metotlar genellikle genişletme metotlarıdır.
5 | Extension Method'lar statik sınıflarda statik metotlar ile yazılır.
6 | this keyword ile başlayan ilk parametre hangi tipi genişleteceğimizi belirtir.
7 | Örneğin aşağıdaki WriteSmart metodu String sınıfı için bir genişletme metodudur.
8 | */
9 | public static class StingExtensions
10 | {
11 | public static string WriteSmart(this string text,char seperator)
12 | {
13 | var result = string.Empty;
14 | for (int i = 0; i < text.Length; i++)
15 | {
16 | result += text[i] + seperator.ToString();
17 | }
18 |
19 | return result;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Chapter09/Chapter09.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Chapter09/EventSample.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter09;
2 |
3 | internal static class EventSample
4 | {
5 | public static void Run()
6 | {
7 | /*
8 | StockService nesne örneğine(stockService), StockLevelChanged isimli event yüklenir.
9 | Bu += operatörü ile yapılabilir.
10 | Bu event gerçekleştiğinde StockService_StockLevelChanged isimli metot çağrılacaktır.
11 | */
12 | var stockServiceLondon = new StockService
13 | {
14 | Owner = "London"
15 | };
16 | var stockServiceNewYork = new StockService
17 | {
18 | Owner = "New York"
19 | };
20 | /*
21 | İstersek birden fazla nesneyi aynı event method'a yönlendirebiliriz.
22 | Aşağıdaki örnekte stockServiceLondon ve stockServiceNewyork nesne örneklerinin
23 | aynı StockLevelChanged event metoduna bağlandığını görebiliriz.
24 | Event method'un ilk parametresi (object sender) ile de olayın sahibi olan nesneyi anlayabiliriz?
25 | */
26 | stockServiceLondon.StockLevelChanged += StockService_StockLevelChanged;
27 | stockServiceNewYork.StockLevelChanged += StockService_StockLevelChanged;
28 | stockServiceLondon.Level = 90; // Burada event tetiklenir.
29 | stockServiceLondon.Level -= 5;
30 | stockServiceNewYork.Level = 45;
31 | }
32 |
33 | // Event Method
34 | private static void StockService_StockLevelChanged(object? sender, StockLevelChangedEventArgs args)
35 | {
36 | /*
37 | Bu event metoda stok seviyesi değişmeden önceki stok seviyesi ile değiştikten sonraki stok seviyesi
38 | bilgilerini taşımak istiyorum. Nasıl taşırsınız?
39 |
40 | Bunun için StockLevelChangedEventArgs isimli sınıfı kullanıyoruz.
41 |
42 | Aşağıdaki gibi event'i tetikleyen nesne örneğinin cast ederek yakalayabiliriz.
43 | */
44 | if (sender is StockService eventOwner)
45 | {
46 | Console.WriteLine($"{eventOwner.Owner}. Stok seviyesinin eski değeri {args.OldLevel}. Değişim {args.Change}");
47 | }
48 | else
49 | {
50 | Console.WriteLine($"Stok seviyesinin eski değeri {args.OldLevel}. Değişim {args.Change}");
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Chapter09/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter09;
2 |
3 | internal class Program
4 | {
5 | static void Main()
6 | {
7 | EventSample.Run();
8 | Console.WriteLine("Program sonu");
9 | }
10 | }
--------------------------------------------------------------------------------
/Chapter09/StockService.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter09;
2 |
3 | /*
4 | StockService nesnesini kullanan object user'lara stok seviyesi değiştiğinde
5 | işleyebilecekleri bir metot sunmak istiyoruz. (Event Method)
6 |
7 | Event : Stok seviyesinin değişmesi
8 |
9 | Event kavramı, delegate tipi ile doğrudan ilişkilidir. Bir event'in tetiklenmesi (trigger)
10 | o event ile ilişkilendirilmiş bir metodun çalışma zamanında işletilmesidir. Çalışma zamanında bir metodu
11 | işaret etmek içinse delegate tipinden yararlanılır.
12 |
13 | Event temsilcileri genellikle geriye değer döndürmeyen, iki parametre alan metotları tanımlar.
14 | İlk parametre event'in sahibi olan nesnedir. İkinci parametre ise event ile ilgili ekstra bilgiler taşımak için kullanılır.
15 | Event temsilcileri isimlendirme standardı gereği EventHandler kelimeleri ile biter.
16 | */
17 |
18 | internal delegate void StockLevelChangedEventHandler(object sender, StockLevelChangedEventArgs args);
19 |
20 | // Olaylara ekstra bilgi taşımak istediğimizde isimlendirme standardı gereği sonu EventArgs ile biten bir sınıf kullanılır
21 | internal class StockLevelChangedEventArgs
22 | {
23 | public int OldLevel { get; set; }
24 | public int Change { get; set; }
25 | }
26 |
27 | internal class StockService
28 | {
29 | /*
30 | StockLevelChanged isimli event, StockService için tanımlanmış bir olaydır.
31 | Bu olay gerçekleştiğinde(ya da tetiklendiğinde), StockLevelChangedEventHandler delegate türü
32 | tarafından işaret edilebilen bir metod çağrılır.
33 | */
34 | // public event StockLevelChangedEventHandler StockLevelChanged;
35 |
36 | /*
37 | Genellikle EventArgs yapısı değişen event'ler söz konusu ise,
38 | .Net ile built-in gelen generic EventHandler temsilcisi de kullanılabilir.
39 | Buna göre kendi delegate türlerimizi yazmaya gerek kalmadan da event'ler oluşturabiliriz.
40 | */
41 | public event EventHandler StockLevelChanged;
42 |
43 | public string Owner { get; set; }
44 |
45 | private int _level;
46 | public int Level
47 | {
48 | get
49 | {
50 | return _level;
51 | }
52 | set
53 | {
54 | /*
55 | Aşağıdaki kullanımı ele alalım.
56 | Eğer StockService nesne örneğinin (object instance) kullanıldığı yerde,
57 | bu nesneye StockLevelChanged event'i bağlanmışsa (event binding)
58 | o event'in işaret ettiği fonksiyonu çağır.
59 |
60 | this keyword'ü, StockService sınıfının çalışma zamanındaki nesne örneğini işaret eder.
61 | */
62 | //if (StockLevelChanged != null)
63 | //{
64 | // StockLevelChanged(this);
65 | //}
66 | var eventArgs = new StockLevelChangedEventArgs
67 | {
68 | OldLevel = value,
69 | Change = _level - value
70 | };
71 |
72 | _level = value;
73 |
74 | StockLevelChanged?.Invoke(this, eventArgs);
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/Chapter10/Chapter10.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Chapter10/ColumnAttribute.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter10
2 | {
3 | /*
4 | ColumnAttribute'u sadece field ve property türlerine uygulanabilir.
5 | Attribute'lar Attribute türünden türemelidir.
6 | */
7 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
8 | internal class ColumnAttribute
9 | : Attribute
10 | {
11 | public string Name { get; set; }
12 | public bool PrimaryKey { get; set; } = false;
13 | public int Length { get; set; }
14 | public string DataType { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Chapter10/DataType.cs:
--------------------------------------------------------------------------------
1 | namespace Cshapter10;
2 |
3 | internal class DataType
4 | {
5 | }
6 | internal class SqlDataType : DataType
7 | {
8 | public const string Text = "nvarchar";
9 | public const string Decimal = "decimal";
10 | public const string Bool = "bit";
11 | public const string BigInt = "bigint";
12 | }
13 |
--------------------------------------------------------------------------------
/Chapter10/MigrationProvider.cs:
--------------------------------------------------------------------------------
1 | using Chapter10.Model;
2 | using Cshapter10;
3 | using System.Reflection;
4 | using System.Text;
5 |
6 | namespace Chapter10;
7 |
8 | /*
9 | Kendisine verilen nesneler için gerekli SQL Tablo oluşturma script'lerini üretir.
10 | Bir nevi otomatik kod üretici olarak düşünebiliriz.
11 | Kendisine ait bir runtime'ı vardır. Dolayısıyla çalışma zamanında okuduğu sınıflar için
12 | Create Table script'leri hazırlar.
13 |
14 | EF'in Migration Tool'u (CLI) göz önüne getirilebilir.
15 | */
16 | internal class MigrationProvider
17 | {
18 | /*
19 | CrateTableScript metodu EntityBase sınıfından türemiş sınıflarla çalışacak şekilde
20 | tasarlanmıştır. Görevi, instance örneğinin Table ve Column attribute'larını tarayıp
21 | uygun Create Table script'ini üretmektir
22 | */
23 | public static string CreateTableScript(T instance)
24 | where T : EntityBase
25 | {
26 | var builder = new StringBuilder();
27 | builder.Append("CREATE OR ALTER TABLE ");
28 | var instanceType = typeof(T); // Burada instance değişkeni ile gelen type bilgisini yakalarız
29 |
30 | // TableAttribute'u yakalıyoruz
31 | var tableAttribute = instanceType.GetCustomAttribute();
32 | if (tableAttribute != null) // Eğer uygulanmışsa şema adı ve tablo adını kullan
33 | {
34 | builder.AppendLine($"{tableAttribute.Schema}.{tableAttribute.Name} (");
35 | }
36 | else // Eğer TableAttribute uygulanmamışsa varsayılan tablo adı için sınıf adı kullanılabilir
37 | {
38 | builder.AppendLine($"{instanceType.Name} (");
39 | }
40 |
41 | // Type üzerindeki tüm property üyelerini dolaşıyoruz.
42 | foreach (var property in instanceType.GetProperties())
43 | {
44 | // Eğer bu özellik ColumnAttribute'u uygulamışsa kolonları ona göre ekliyoruz
45 | var columnAttribute = property.GetCustomAttribute();
46 | if (columnAttribute != null)
47 | {
48 | // Text türünde bir alansa length bilgisi gerekeceğinden bu tip bir ayrıma gittik
49 | if (columnAttribute.DataType == SqlDataType.Text)
50 | {
51 | builder.AppendLine($"\t{columnAttribute.Name} {columnAttribute.DataType}({columnAttribute.Length}),");
52 | }else
53 | {
54 | builder.AppendLine($"\t{columnAttribute.Name} {columnAttribute.DataType},");
55 | }
56 | }
57 | else
58 | {
59 | builder.AppendLine($"\t{property.Name},");
60 | //TODO@buraksenyurt Eğer ColumnAttribute uygulanmadıysa özellik tipine bakarak varsayılan bir tanımlama yapılmalı
61 | }
62 | }
63 |
64 | var script = builder.ToString()[..(builder.Length - 3)] + "\n)\nGo";
65 | return script;
66 | }
67 |
68 | internal static void SaveScript(string script, string filePath)
69 | {
70 | var fPath = Path.Combine(Environment.CurrentDirectory,filePath);
71 | File.WriteAllText(fPath,script);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/Chapter10/Model/EntityBase.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter10.Model;
2 |
3 | internal class EntityBase
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/Chapter10/Model/Product.cs:
--------------------------------------------------------------------------------
1 | using Cshapter10;
2 |
3 | namespace Chapter10.Model;
4 |
5 | /*
6 | Product sınıfını MigrationProvider senaryo gereği bir runtime olarak okur.
7 | Amacı bu sınıfa ve üyelerine bakıp bir SQL Table Create script' i oluşturmaktır.
8 | Bunun için Table ve Column Attribute sınıfları ile, runtime'a ekstra bilgiler taşınır.
9 | Örneğin, tablo adı ve şeması ne olacak, property'ler kolon haline çevrilirken hangi
10 | veri türünden olacak vs
11 | */
12 |
13 | [Table(Schema = "Catalog", Name = "Products")]
14 | internal class Product
15 | : EntityBase
16 | {
17 | [Column(Name = "p_id", DataType = SqlDataType.BigInt, PrimaryKey = true)]
18 | public int Id { get; set; }
19 | [Column(Name = "p_title", DataType = SqlDataType.Text, Length = 50)]
20 | public string Title { get; set; }
21 | [Column(Name = "p_list_price", DataType = SqlDataType.Decimal)]
22 | public decimal ListPrice { get; set; }
23 | [Column(Name = "p_in_stock", DataType = SqlDataType.Bool)]
24 | public bool InStock { get; set; }
25 | }
26 |
--------------------------------------------------------------------------------
/Chapter10/Program.cs:
--------------------------------------------------------------------------------
1 | using Chapter10.Model;
2 |
3 | namespace Chapter10
4 | {
5 | internal class Program
6 | {
7 | static void Main()
8 | {
9 | Product product = new Product
10 | {
11 | Id = 1,
12 | Title = "Dolma kalem",
13 | InStock = true,
14 | ListPrice = 10.0M
15 | };
16 | var script = MigrationProvider.CreateTableScript(product); // product isimli nesne örneği için Create Table script'ini üret
17 | Console.WriteLine($"{script}");
18 | MigrationProvider.SaveScript(script,"CreateProduct.sql");
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Chapter10/TableAttribute.cs:
--------------------------------------------------------------------------------
1 | namespace Chapter10
2 | {
3 | /*
4 | Attribute sınıfları Attribute kelimesi ile bitecek şekilde isimlendirilir ve Attribute sınıfından türer.
5 | AttributeUsage isimli bir başka Attribute ile imzalanarak hangi seviye uygulanacakları belirtilebilir.
6 | Örneğin TableAttribute sadece sınıflara uygulanabilir.
7 | ColumnAttribute ise sadece Property'lere veya Field'lara uygulanabilir.
8 | */
9 | [AttributeUsage(AttributeTargets.Class)]
10 | internal class TableAttribute
11 | : Attribute
12 | {
13 | public string Schema { get; set; }
14 | public string Name { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/FreeZone/Azon.Games/Azon.Games.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/FreeZone/Azon.Games/Category.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Games;
2 |
3 | public class Category
4 | {
5 | public int Id { get; set; }
6 | public string Name { get; set; }
7 | }
8 |
--------------------------------------------------------------------------------
/FreeZone/Azon.Games/Game.cs:
--------------------------------------------------------------------------------
1 | namespace Azon.Games;
2 |
3 | public class Game
4 | {
5 | public int Id { get; set; }
6 | public string Name { get; set; }
7 | public short ReleaseYear { get; set; }
8 | public bool OnSale { get; set; }
9 | public double UserRate { get; set; }
10 | public Category Category { get; set; }
11 | public double ListPrice { get; set; }
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Abstractions/ConsoleLogger.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Abstractions;
2 |
3 | public class ConsoleLogger
4 | : ILogger
5 | {
6 | public void Error(string message)
7 | {
8 | Console.WriteLine($"ERROR:{DateTime.Now}|{message}");
9 | }
10 |
11 | public void Info(string message)
12 | {
13 | Console.WriteLine($"INFO:{DateTime.Now}|{message}");
14 | }
15 |
16 | public void Warn(string message)
17 | {
18 | Console.WriteLine($"WARN:{DateTime.Now}|{message}");
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Abstractions/ElasticLogger.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Abstractions;
2 |
3 | public class ElasticLogger
4 | : ILogger
5 | {
6 | public void Error(string message)
7 | {
8 | // Elasticsearch veritabanına error log basar
9 | }
10 |
11 | public void Info(string message)
12 | {
13 | // Elasticsearch veritabanına info log basar
14 | }
15 |
16 | public void Warn(string message)
17 | {
18 | // Elasticsearch veritabanına warn log basar
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Abstractions/ILogger.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Abstractions;
2 |
3 | public interface ILogger
4 | {
5 | void Info(string message);
6 | void Warn(string message);
7 | void Error(string message);
8 | }
9 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Abstractions/InvalidRoleException.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Abstractions;
2 |
3 | public class InvalidRoleException
4 | :Exception
5 | {
6 | public MemberRole Role { get; set; }
7 | }
8 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Abstractions/Learning.Abstractions.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Abstractions/Member.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Abstractions;
2 |
3 | public class Member
4 | {
5 | public int Id { get; set; }
6 | public string Fullname { get; set; }
7 | public DateTime LastLogin { get; set; }
8 | public DateTime Created { get; set; }
9 | public MemberRole Role { get; set; }
10 | }
11 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Abstractions/MemberRole.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Abstractions;
2 |
3 | public class MemberRole
4 | {
5 | public string Name { get; set; }
6 | public string Description { get; set; }
7 | }
8 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Abstractions/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Abstractions;
2 |
3 | internal class Program
4 | {
5 | static void Main()
6 | {
7 | var consoleLogger = new ConsoleLogger();
8 | var roleProvider = new RoleProvider(consoleLogger);
9 | var member = new Member()
10 | {
11 | Id = 1,
12 | Role = new MemberRole
13 | {
14 | Name = "Hacker",
15 | Description = "All roles"
16 | },
17 | Created = DateTime.UtcNow.AddYears(-1),
18 | Fullname = "Mario Bross",
19 | LastLogin = DateTime.UtcNow.AddDays(1),
20 | };
21 | var authorized = roleProvider.IsAuthorized(member);
22 | Console.WriteLine(authorized);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Abstractions/RoleProvider.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Abstractions;
2 |
3 | public class RoleProvider(ILogger logger)
4 | {
5 | private readonly ILogger _logger = logger;
6 |
7 | public bool IsAuthorized(Member member)
8 | {
9 | try
10 | {
11 | if (member.Role.Name == "Administrator")
12 | {
13 | _logger.Info($"{member.Role.Name} geçerli rolde");
14 | return true;
15 | }
16 | else if (member.Role.Name == "StandardUser")
17 | {
18 | _logger.Info($"{member.Role.Name} geçerli rolde");
19 | return true;
20 | }
21 | else
22 | {
23 | throw new InvalidRoleException { Role = member.Role };
24 | }
25 | }
26 | catch (Exception ex)
27 | {
28 | _logger.Error(ex.Message);
29 | // Console.WriteLine(ex.Message);
30 | }
31 | return false;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/FreeZone/Learning.ExtensionMethods/Learning.ExtensionMethods.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/FreeZone/Learning.ExtensionMethods/NumberExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.ExtensionMethods;
2 |
3 | public static class NumberExtensions
4 | {
5 | public static bool IsPrime(this int number)
6 | {
7 | if (number <= 1) return false;
8 |
9 | for (int i = 2; i <= Math.Sqrt(number); i++)
10 | {
11 | if (number % i == 0) return false;
12 | }
13 |
14 | return true;
15 | }
16 |
17 | public static bool IsPalindrome(this int number)
18 | {
19 | string original = number.ToString();
20 | string reversed = new(original.Reverse().ToArray());
21 | return original == reversed;
22 | }
23 |
24 | public static bool IsPerfectNumber(this int number)
25 | {
26 | if (number <= 0) return false;
27 |
28 | int sum = 0;
29 | for (int i = 1; i <= number / 2; i++)
30 | {
31 | if (number % i == 0)
32 | sum += i;
33 | }
34 |
35 | return sum == number;
36 | }
37 |
38 | public static long Factorial(this int number)
39 | {
40 | if (number < 0)
41 | {
42 | throw new ArgumentException("Negatif sayıların faktöriyeli hesaplanamaz.");
43 | }
44 |
45 | long result = 1;
46 | for (int i = 1; i <= number; i++)
47 | {
48 | result *= i;
49 | }
50 | return result;
51 | }
52 |
53 | public static bool IsArmstrongNumber(this int number)
54 | {
55 | if (number < 0) return false;
56 |
57 | var digits = number.ToString().Select(c => int.Parse(c.ToString())).ToArray();
58 | int power = digits.Length;
59 |
60 | int sum = digits.Select(d => (int)Math.Pow(d, power)).Sum();
61 |
62 | return sum == number;
63 | }
64 |
65 | public static List GetFactors(this int number)
66 | {
67 | var factors = new List();
68 |
69 | for (int i = 1; i <= number; i++)
70 | {
71 | if (number % i == 0)
72 | factors.Add(i);
73 | }
74 |
75 | return factors;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/FreeZone/Learning.ExtensionMethods/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.ExtensionMethods;
2 |
3 | internal class Program
4 | {
5 | static void Main()
6 | {
7 | int number = 27;
8 | List factors = number.GetFactors();
9 | Console.WriteLine($"Factors of {number}");
10 | foreach (int f in factors)
11 | {
12 | Console.Write($"{f},");
13 | }
14 | Console.WriteLine();
15 |
16 | number = 121;
17 | Console.WriteLine($"{number} is palindrome number? {number.IsPalindrome()}");
18 |
19 | number = 153;
20 | Console.WriteLine($"{number} is armstrong number? {number.IsArmstrongNumber()}");
21 |
22 | number = 28;
23 | Console.WriteLine($"{number} is perfect number? {number.IsPerfectNumber()}");
24 |
25 | number = 29;
26 | Console.WriteLine($"{number} is prime number? {number.IsPrime()}");
27 |
28 | string paragraph = "Bugün programlama dillerinden rust ile ilgili çalışmalar yapıyorum";
29 | int count = paragraph.WordCount();
30 | Console.WriteLine($"{paragraph}\b has {count} words");
31 |
32 | string word = "Madam";
33 | bool isPalindromeWord = word.IsPalindrome();
34 | Console.WriteLine($"{word} is palindrome word? {isPalindromeWord}");
35 |
36 | string input = "Klimanjoro sokak Numara 1234, Daire 32, Posto Kodu 19, Tokyo";
37 | string numbers = input.ExtractNumbers();
38 | Console.WriteLine($"{input}\ncontains this {numbers} ");
39 |
40 | Console.WriteLine("Hello World is alphabetic ? {0}", "Hello World!".IsAlphabetic());
41 | Console.WriteLine("John Doe 89 ? {0}", "John Doe 89!".IsAlphabetic());
42 |
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/FreeZone/Learning.ExtensionMethods/StringExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.ExtensionMethods;
2 |
3 | public static class StringExtensions
4 | {
5 | public static string FirstNCharacters(this string text, int n)
6 | {
7 | if (string.IsNullOrEmpty(text) || n <= 0)
8 | {
9 | return string.Empty;
10 | }
11 |
12 | return text.Length <= n ? text : text[..n];
13 | }
14 |
15 | public static bool IsPalindrome(this string text)
16 | {
17 | if (string.IsNullOrEmpty(text))
18 | {
19 | return false;
20 | }
21 |
22 | var reversed = new string(text.ToLower().Where(char.IsLetterOrDigit).Reverse().ToArray());
23 | var original = new string(text.ToLower().Where(char.IsLetterOrDigit).ToArray());
24 |
25 | return original == reversed;
26 | }
27 |
28 | public static int WordCount(this string text)
29 | {
30 | if (string.IsNullOrWhiteSpace(text))
31 | {
32 | return 0;
33 | }
34 |
35 | return text.Split([' ', '\t', '\n'], StringSplitOptions.RemoveEmptyEntries).Length;
36 | }
37 |
38 | public static bool AnyNumber(this string text)
39 | {
40 | return text.Any(char.IsDigit);
41 | }
42 |
43 | public static bool IsAlphabetic(this string text)
44 | {
45 | return !string.IsNullOrEmpty(text) && text.All(char.IsLetter);
46 | }
47 |
48 | public static string ExtractNumbers(this string text)
49 | {
50 | return new string(text.Where(char.IsDigit).ToArray());
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Generics/IRepository.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Generics;
2 |
3 | public interface IRepository
4 | {
5 | void Add(T item);
6 | T GetById(int id);
7 | IEnumerable GetAll();
8 | }
--------------------------------------------------------------------------------
/FreeZone/Learning.Generics/InMemoryRepository.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Generics;
2 |
3 | public class InMemoryRepository
4 | : IRepository where T : class
5 | {
6 | private readonly Dictionary _store = [];
7 | private int _nextId = 1;
8 |
9 | public void Add(T item)
10 | {
11 | _store[_nextId++] = item;
12 | }
13 |
14 | public T GetById(int id)
15 | {
16 | return _store.TryGetValue(id, out T? value) ? value : null;
17 | }
18 |
19 | public IEnumerable GetAll()
20 | {
21 | return _store.Values;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Generics/Learning.Generics.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Generics/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Generics;
2 |
3 | internal class Program
4 | {
5 | static void Main()
6 | {
7 | var gameRepository = new InMemoryRepository();
8 |
9 | gameRepository.Add(new Game { Id = 1, Name = "Bulders Gate" });
10 | gameRepository.Add(new Game { Id = 2, Name = "Hades II" });
11 | gameRepository.Add(new Game { Id = 3, Name = "Super Mario" });
12 |
13 | foreach (var game in gameRepository.GetAll())
14 | {
15 | Console.WriteLine($"{game.Id} - {game.Name}");
16 | }
17 |
18 | var catalogRepository = new InMemoryRepository();
19 |
20 | catalogRepository.Add(new Product { Id = 1, Title = "Blue Ray Player", ListPrice = 10 });
21 | catalogRepository.Add(new Product { Id = 2, Title = "Wireless Kulaklık", ListPrice = 8 });
22 |
23 | foreach (var product in catalogRepository.GetAll())
24 | {
25 | Console.WriteLine($"{product.Title} ({product.ListPrice} Coin)");
26 | }
27 | }
28 | }
29 |
30 | class Game
31 | {
32 | public int Id { get; set; }
33 | public string Name { get; set; }
34 | }
35 |
36 | class Product
37 | {
38 | public int Id { get; set; }
39 | public string Title { get; set; }
40 | public decimal ListPrice { get; set; }
41 | }
--------------------------------------------------------------------------------
/FreeZone/Learning.Interfaces/Category.cs:
--------------------------------------------------------------------------------
1 | namespace LearningInterfaces
2 | {
3 | public class Category
4 | : IComparable
5 | {
6 | public string? Title { get; set; }
7 |
8 | public int CompareTo(Category? other)
9 | {
10 | if (other == null)
11 | return 1;
12 |
13 | return Title.CompareTo(other.Title);
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Interfaces/Learning.Interfaces.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Interfaces/Player.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | namespace LearningInterfaces
4 | {
5 | public class Player : INotifyPropertyChanged
6 | {
7 | private int _score;
8 | public int Score
9 | {
10 | get => _score;
11 | set
12 | {
13 | if (_score != value)
14 | {
15 | var oldScore = _score;
16 | _score = value;
17 | OnScoreChanged(nameof(Score), oldScore, _score);
18 | }
19 | }
20 | }
21 |
22 | public event PropertyChangedEventHandler? PropertyChanged;
23 |
24 | protected virtual void OnScoreChanged(string propertyName, int oldValue, int newValue)
25 | {
26 | PropertyChanged?.Invoke(this, new ScorePropertyChangedEventArgs(propertyName, oldValue, newValue));
27 | }
28 | }
29 |
30 | public class ScorePropertyChangedEventArgs
31 | : PropertyChangedEventArgs
32 | {
33 | public int OldValue { get; }
34 | public int NewValue { get; }
35 |
36 | public ScorePropertyChangedEventArgs(string propertyName, int oldValue, int newValue)
37 | : base(propertyName)
38 | {
39 | OldValue = oldValue;
40 | NewValue = newValue;
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Interfaces/Product.cs:
--------------------------------------------------------------------------------
1 | namespace LearningInterfaces
2 | {
3 | public class Product : IEquatable
4 | {
5 | public string? Title { get; set; }
6 | public decimal Price { get; set; }
7 |
8 | public bool Equals(Product? otherProduct)
9 | {
10 | if (otherProduct == null)
11 | return false;
12 |
13 | return Title == otherProduct.Title && Price == otherProduct.Price;
14 | }
15 |
16 | public override bool Equals(object? obj)
17 | {
18 | return Equals(obj as Product);
19 | }
20 | public override int GetHashCode()
21 | {
22 | return HashCode.Combine(Title, Price);
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Interfaces/Program.cs:
--------------------------------------------------------------------------------
1 | namespace LearningInterfaces
2 | {
3 | internal class Program
4 | {
5 | static void Main()
6 | {
7 | #region IEnumerable Örneği
8 |
9 | var gameWorld = new World();
10 | foreach (var entity in gameWorld)
11 | {
12 | Console.WriteLine(entity.Id);
13 | }
14 |
15 | #endregion
16 |
17 | #region IComparable Örneği
18 |
19 |
20 | var categories = new List
21 | {
22 | new() { Title = "Elektronik"},
23 | new() { Title = "Beyaz Eşya"},
24 | new() { Title = "Züccaciye"},
25 | new() { Title = "Kitap"},
26 | new() { Title = "Kırtasiye"},
27 | new() { Title = "Dergi"},
28 | new() { Title = "Gazete"},
29 | };
30 | categories.Sort();
31 | foreach (var category in categories)
32 | {
33 | Console.WriteLine(category.Title);
34 | }
35 |
36 | #endregion
37 |
38 | #region IFormattable Örneği
39 |
40 | var currentTemperature = new Temperature { Celsius = 18 };
41 | Console.WriteLine(currentTemperature.ToString("C", null));
42 | Console.WriteLine(currentTemperature.ToString("F", null));
43 |
44 | #endregion
45 |
46 | #region IEquatable Örneği
47 |
48 | var prd1 = new Product { Title = "ElGi Tv", Price = 999.99M };
49 | var prd2 = new Product { Title = "ElGi T", Price = 999.99M };
50 | Console.WriteLine("Product 1 ile Product 2 verileri eşit mi? {0}", prd1.Equals(prd2));
51 |
52 | #endregion
53 |
54 | #region INotifyPropertyChanged Örneği
55 |
56 | var obiWanKenobi = new Player();
57 | obiWanKenobi.Score = 10;
58 | obiWanKenobi.PropertyChanged += (sender, args) =>
59 | {
60 | if (args is ScorePropertyChangedEventArgs e)
61 | {
62 | Console.WriteLine($"{e.PropertyName} değeri {e.OldValue} ' dan {e.NewValue} olarak değişti!");
63 | }
64 | };
65 | obiWanKenobi.Score = 23;
66 |
67 | #endregion
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Interfaces/Temperature.cs:
--------------------------------------------------------------------------------
1 | namespace LearningInterfaces
2 | {
3 | public class Temperature
4 | : IFormattable
5 | {
6 | public double Celsius { get; set; }
7 |
8 | public string ToString(string format, IFormatProvider formatProvider)
9 | {
10 | return format switch
11 | {
12 | "F" => $"{Celsius * 9 / 5 + 32} °F",
13 | "C" => $"{Celsius} °C",
14 | _ => Celsius.ToString()
15 | };
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Interfaces/World.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 |
3 | namespace LearningInterfaces
4 | {
5 | public class World
6 | : IEnumerable
7 | {
8 | private readonly List _entities =
9 | [
10 | new Tower{Id=1 },
11 | new Tower{Id=2 },
12 | new Tower{Id=3 },
13 | new Wall{Id=4 },
14 | new Wall{Id=5 },
15 | new Tile{Id=6 },
16 | new Wall{Id=7 },
17 | ];
18 |
19 | public IEnumerator GetEnumerator()
20 | {
21 | return _entities.GetEnumerator();
22 | }
23 |
24 | IEnumerator IEnumerable.GetEnumerator()
25 | {
26 | return GetEnumerator();
27 | }
28 | }
29 |
30 | public class GameEntity
31 | {
32 | public int Id;
33 | }
34 | public class Wall : GameEntity { }
35 | public class Tile : GameEntity { }
36 | public class Tower : GameEntity { }
37 | }
38 |
--------------------------------------------------------------------------------
/FreeZone/Learning.LINQ/GameQueries.cs:
--------------------------------------------------------------------------------
1 | using Azon.Games;
2 |
3 | namespace Learning.LINQ;
4 |
5 | public static class GameQueries
6 | {
7 | public static List GetGamesByCategory(List games, string categoryName)
8 | {
9 | return games.Where(game => game.Category.Name.Contains(categoryName, StringComparison.OrdinalIgnoreCase)).ToList();
10 | }
11 |
12 | public static List GetGamesByReleaseYear(List games, int year)
13 | {
14 | return games.Where(game => game.ReleaseYear >= year).ToList();
15 | }
16 |
17 | public static List GetGamesByUserRate(List games, double minRate)
18 | {
19 | return games.Where(game => game.UserRate > minRate).ToList();
20 | }
21 |
22 | public static List GetGamesOnSale(List games)
23 | {
24 | return games.Where(game => game.OnSale).ToList();
25 | }
26 |
27 | public static List GetGamesByPriceRange(List games, double minPrice, double maxPrice)
28 | {
29 | return games.Where(game => game.ListPrice >= minPrice && game.ListPrice <= maxPrice).ToList();
30 | }
31 |
32 | public static List GetTopRatedGames(List games)
33 | {
34 | double maxRate = games.Max(game => game.UserRate);
35 | return games.Where(game => game.UserRate == maxRate).ToList();
36 | }
37 |
38 | public static Dictionary> GetGamesGroupedByYear(List games)
39 | {
40 | return games.GroupBy(game => game.ReleaseYear)
41 | .ToDictionary(group => group.Key, group => group.ToList());
42 | }
43 |
44 | public static List GetGamesSortedByName(List games)
45 | {
46 | return games.OrderBy(game => game.Name).ToList();
47 | }
48 |
49 | public static List GetTop5CheapestGames(List games)
50 | {
51 | return games.OrderBy(game => game.ListPrice).Take(5).ToList();
52 | }
53 |
54 | public static Dictionary GetAverageRatingByCategory(List games)
55 | {
56 | return games.GroupBy(game => game.Category.Name)
57 | .ToDictionary(group => group.Key, group => group.Average(game => game.UserRate));
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/FreeZone/Learning.LINQ/GameQueriesV2.cs:
--------------------------------------------------------------------------------
1 | using Azon.Games;
2 |
3 | namespace Learning.LINQ;
4 |
5 | public static class GameQueriesV2
6 | {
7 | public static List GetGamesByCategory(List games, string categoryName)
8 | {
9 | var query = from game in games
10 | where game.Category.Name.Contains(categoryName, StringComparison.OrdinalIgnoreCase)
11 | select game;
12 |
13 | return query.ToList();
14 | }
15 |
16 | public static List GetGamesByReleaseYear(List games, int year)
17 | {
18 | var query = from game in games
19 | where game.ReleaseYear >= year
20 | select game;
21 |
22 | return query.ToList();
23 | }
24 |
25 | public static List GetGamesByUserRate(List games, double minRate)
26 | {
27 | var query = from game in games
28 | where game.UserRate > minRate
29 | select game;
30 |
31 | return query.ToList();
32 | }
33 |
34 | public static List GetGamesOnSale(List games)
35 | {
36 | var query = from game in games
37 | where game.OnSale
38 | select game;
39 |
40 | return query.ToList();
41 | }
42 |
43 | public static List GetGamesByPriceRange(List games, double minPrice, double maxPrice)
44 | {
45 | var query = from game in games
46 | where game.ListPrice >= minPrice && game.ListPrice <= maxPrice
47 | select game;
48 |
49 | return query.ToList();
50 | }
51 |
52 | public static List GetTopRatedGames(List games)
53 | {
54 | var maxRate = (from game in games
55 | select game.UserRate).Max();
56 |
57 | var query = from game in games
58 | where game.UserRate == maxRate
59 | select game;
60 |
61 | return query.ToList();
62 | }
63 |
64 | public static Dictionary> GetGamesGroupedByYear(List games)
65 | {
66 | var query = from game in games
67 | group game by game.ReleaseYear into yearGroup
68 | select yearGroup;
69 |
70 | return query.ToDictionary(group => group.Key, group => group.ToList());
71 | }
72 |
73 | public static List GetGamesSortedByName(List games)
74 | {
75 | var query = from game in games
76 | orderby game.Name
77 | select game;
78 |
79 | return query.ToList();
80 | }
81 |
82 | public static List GetTop5CheapestGames(List games)
83 | {
84 | var query = (from game in games
85 | orderby game.ListPrice
86 | select game).Take(5);
87 |
88 | return query.ToList();
89 | }
90 |
91 | public static Dictionary GetAverageRatingByCategory(List games)
92 | {
93 | var query = from game in games
94 | group game by game.Category.Name into categoryGroup
95 | select new
96 | {
97 | Category = categoryGroup.Key,
98 | AverageRating = categoryGroup.Average(game => game.UserRate)
99 | };
100 |
101 | return query.ToDictionary(result => result.Category, result => result.AverageRating);
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/FreeZone/Learning.LINQ/Learning.LINQ.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/FreeZone/Learning.LINQ/Program.cs:
--------------------------------------------------------------------------------
1 | using Azon.Games;
2 |
3 | namespace Learning.LINQ;
4 |
5 | internal class Program
6 | {
7 | static void Main()
8 | {
9 | var catalog = new Catalog();
10 | var games = catalog.LoadGames();
11 |
12 | #region Extension Methods ile
13 |
14 | var strategyGames = GameQueries.GetGamesByCategory(games, "Strategy");
15 | var recentGames = GameQueries.GetGamesByReleaseYear(games, 2000);
16 | var highRatedGames = GameQueries.GetGamesByUserRate(games, 9.0);
17 | var saleGames = GameQueries.GetGamesOnSale(games);
18 | var midRangeGames = GameQueries.GetGamesByPriceRange(games, 20, 50);
19 | var topRatedGames = GameQueries.GetTopRatedGames(games);
20 | var groupedByYear = GameQueries.GetGamesGroupedByYear(games);
21 | var sortedGames = GameQueries.GetGamesSortedByName(games);
22 | var cheapestGames = GameQueries.GetTop5CheapestGames(games);
23 | var averageRatings = GameQueries.GetAverageRatingByCategory(games);
24 |
25 | #endregion
26 |
27 | #region LINQ Query Syntax ile
28 |
29 | var rpgGames = GameQueriesV2.GetGamesByCategory(games, "RPG");
30 | var recentGames2 = GameQueriesV2.GetGamesByReleaseYear(games, 2010);
31 | var highRatedGames2 = GameQueriesV2.GetGamesByUserRate(games, 9.5);
32 | var salesGames2 = GameQueriesV2.GetGamesOnSale(games);
33 | var midRangeGames2 = GameQueriesV2.GetGamesByPriceRange(games, 10, 50);
34 | var topRatedGames2 = GameQueriesV2.GetTopRatedGames(games);
35 | var groupedByYear2 = GameQueriesV2.GetGamesGroupedByYear(games);
36 | var sortedGames2 = GameQueriesV2.GetGamesSortedByName(games);
37 | var cheapestGames2 = GameQueriesV2.GetTop5CheapestGames(games);
38 | var averageRatings2 = GameQueriesV2.GetAverageRatingByCategory(games);
39 |
40 |
41 | #endregion
42 |
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Loops/Learning.Loops.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Loops/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Loops
2 | {
3 | internal class Program
4 | {
5 | static void Main()
6 | {
7 | Terminal.ForLoopExample();
8 | Terminal.WhileLoopExample();
9 | Terminal.DoWhileLoopExample();
10 | Terminal.ForeachLoopExample();
11 | var booksStartsWithA = Terminal.GetBooksStartingWith('A');
12 | Terminal.PrintBooks(booksStartsWithA);
13 | var booksStartsWithX = Terminal.GetBooksStartingWith('X');
14 | Terminal.PrintBooks(booksStartsWithX);
15 |
16 | var forWords = Terminal.GetBooksContainingWord("for");
17 | Terminal.PrintBooks(forWords);
18 |
19 | var greaterThan3 = Terminal.GetBooksWithWordCountGreaterThan(3);
20 | Terminal.PrintBooks(greaterThan3);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Loops/Terminal.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Loops
2 | {
3 | /*
4 | Aşağıdaki sınıfta temel döngü kullanımlarına ait bazı örnekler yer almaktadır.
5 | */
6 | public static class Terminal
7 | {
8 | static readonly string[] books = {
9 | "Dune", "Neuromancer", "Snow Crash", "Hyperion", "The Left Hand of Darkness",
10 | "Foundation", "Brave New World", "The Stars My Destination", "The Dispossessed",
11 | "Fahrenheit 451", "1984", "Ubik", "Do Androids Dream of Electric Sheep?", "Solaris",
12 | "The Man in the High Castle", "A Canticle for Leibowitz", "The Forever War",
13 | "The Moon is a Harsh Mistress", "Rendezvous with Rama", "Ringworld", "I, Robot",
14 | "The Demolished Man", "The Martian Chronicles", "Childhood's End",
15 | "The Time Machine", "The War of the Worlds", "The Lathe of Heaven",
16 | "Altered Carbon", "Stranger in a Strange Land", "The Day of the Triffids",
17 | "The Three-Body Problem", "The Windup Girl", "Blindsight", "Ancillary Justice",
18 | "The Expanse: Leviathan Wakes", "The Handmaid's Tale", "The Diamond Age",
19 | "The City and the Stars", "The Sirens of Titan", "A Fire Upon the Deep",
20 | "The Inverted World", "Old Man's War", "The Road", "The Book of the New Sun",
21 | "Perdido Street Station", "The Drowned Cities", "The Iron Dream",
22 | "The Player of Games", "The Culture: Consider Phlebas", "Accelerando",
23 | "The Hunger Games", "The Dark Forest", "A Scanner Darkly"
24 | };
25 |
26 | // Foreach döngüsü örneği
27 | public static void ForeachLoopExample()
28 | {
29 | Console.WriteLine("Foreach Loop Example:");
30 | int i = 1;
31 | foreach (var book in books)
32 | {
33 | Console.WriteLine($"{i}, {book}");
34 | i++;
35 | }
36 | Console.WriteLine();
37 | }
38 |
39 | // For döngüsü örneği
40 | public static void ForLoopExample()
41 | {
42 | Console.WriteLine("For Loop Example:");
43 | for (int i = 0; i < books.Length; i++)
44 | {
45 | Console.WriteLine($"{i + 1}, {books[i]}");
46 | }
47 | Console.WriteLine();
48 | }
49 |
50 | // While döngüsü örneği
51 | public static void WhileLoopExample()
52 | {
53 | Console.WriteLine("While Loop Example:");
54 | int i = 0;
55 | while (i < books.Length)
56 | {
57 | Console.WriteLine($"{i + 1}, {books[i]}");
58 | i++;
59 | }
60 | Console.WriteLine();
61 | }
62 |
63 | // Do-While döngüsü örneği
64 | public static void DoWhileLoopExample()
65 | {
66 | Console.WriteLine("Do-While Loop Example:");
67 | int i = 0;
68 | do
69 | {
70 | Console.WriteLine($"{i + 1}, {books[i]}");
71 | i++;
72 | } while (i < books.Length);
73 | Console.WriteLine();
74 | }
75 |
76 | public static List GetBooksStartingWith(char letter)
77 | {
78 | List result = [];
79 | int i = 0;
80 | bool found = false;
81 | do
82 | {
83 | if (books[i].StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase))
84 | {
85 | result.Add(books[i]);
86 | found = true;
87 | }
88 | i++;
89 | } while (i < books.Length);
90 |
91 | if (!found)
92 | {
93 | Console.WriteLine($"No books found starting with '{letter}'");
94 | }
95 | return result;
96 | }
97 |
98 | // Kitap içinde belli bir kelime geçenleri döndüren metot
99 | public static List GetBooksContainingWord(string word)
100 | {
101 | List result = [];
102 | for (int i = 0; i < books.Length; i++)
103 | {
104 | if (books[i].Contains(word))
105 | {
106 | result.Add(books[i]);
107 | }
108 | }
109 | return result;
110 | }
111 |
112 | // Belli sayıda kelimeden fazlasına sahip olan kitapları bulan metot
113 | public static List GetBooksWithWordCountGreaterThan(int wordCount)
114 | {
115 | List result = [];
116 | foreach (var book in books)
117 | {
118 | if (book.Split(' ').Length > wordCount)
119 | {
120 | result.Add(book);
121 | }
122 | }
123 | return result;
124 | }
125 |
126 | public static void PrintBooks(List books)
127 | {
128 | Console.WriteLine();
129 | foreach (var book in books)
130 | {
131 | Console.WriteLine(book);
132 | }
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/FreeZone/Learning.SOLID/Basics/DIP/BadPractice.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.SOLID.Basics.DIP;
2 |
3 | /*
4 | DIP prensibi şunu savunur; Yüksek seviyeli modüller, düşük seviyeli modüllere bağımlı olmamalıdır.
5 | Aşağıdaki örnekte Notification bileşeni, EmailNotification bileşenine bağımlıdır. Farklı türde bir bildirim
6 | yapılmak istendiğinde bu mümkün değildir. Örneğin email yerine sms gönderimi söz konusu olabilir.
7 | */
8 | public class EmailNotification
9 | {
10 | public void SendEmail(string message)
11 | {
12 | }
13 | }
14 |
15 | public class Notification
16 | {
17 | private readonly EmailNotification _emailNotification = new();
18 |
19 | public void Notify(string message)
20 | {
21 | _emailNotification.SendEmail(message);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/FreeZone/Learning.SOLID/Basics/DIP/GoodPractice.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.SOLID.Basics.DIP;
2 |
3 | public interface INotifier
4 | {
5 | void Notify(string message);
6 | }
7 |
8 | public class SmsNotifier : INotifier
9 | {
10 | public void Notify(string message)
11 | {
12 | }
13 | }
14 |
15 | public class EmailNotifier : INotifier
16 | {
17 | public void Notify(string message)
18 | {
19 | }
20 | }
21 |
22 | public class VoiceCallNotifier : INotifier
23 | {
24 | public void Notify(string message)
25 | {
26 | }
27 | }
28 |
29 | public class NotificationService
30 | {
31 | private readonly INotifier _notifier;
32 |
33 | public NotificationService(INotifier notifier)
34 | {
35 | _notifier = notifier;
36 | }
37 |
38 | public void Notify(string message)
39 | {
40 | _notifier.Notify(message);
41 | }
42 | }
43 |
44 | public class Application
45 | {
46 | public static void Run()
47 | {
48 | INotifier notifier = new VoiceCallNotifier();
49 | NotificationService service = new NotificationService(notifier);
50 | service.Notify("Bir sonraki ödemeniz için hatırlatma");
51 | }
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/FreeZone/Learning.SOLID/Basics/DIP/MultiUsagePractice.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.SOLID.Basics.DIP;
2 |
3 | public interface INotify
4 | {
5 | void Notify(string message);
6 | }
7 |
8 | public class SmsNotify : INotify
9 | {
10 | public void Notify(string message)
11 | {
12 | }
13 | }
14 |
15 | public class EmailNotify : INotify
16 | {
17 | public void Notify(string message)
18 | {
19 | }
20 | }
21 |
22 | public class VoiceCallNotify : INotify
23 | {
24 | public void Notify(string message)
25 | {
26 | }
27 | }
28 |
29 | public class NotifyService
30 | {
31 | private readonly Queue _notifiers;
32 |
33 | public NotifyService(Queue notifiers)
34 | {
35 | _notifiers = notifiers;
36 | }
37 |
38 | public void Notify(string message)
39 | {
40 | //_notifier.Notify(message);
41 | foreach (INotifier notifier in _notifiers)
42 | {
43 | notifier.Notify(message);
44 | }
45 | }
46 | }
47 |
48 | public class ObjectUser
49 | {
50 | public static void Run()
51 | {
52 | INotify voiceCallNotifier = new VoiceCallNotify();
53 | INotify smsNotifier = new SmsNotify();
54 |
55 | Queue notifiers = new Queue();
56 | notifiers.Enqueue(smsNotifier);
57 | notifiers.Enqueue(voiceCallNotifier);
58 |
59 | NotifyService service = new NotifyService(notifiers);
60 | service.Notify("Bir sonraki ödemeniz için hatırlatma");
61 | }
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/FreeZone/Learning.SOLID/Basics/ISP/BadPractice.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.SOLID.Basics.ISP;
2 |
3 | /*
4 | Interface segregation prensibi bir arayüzün (interface)
5 | onu kullanan tarafın ihtiyacı olmayan metotları içermemelidir der.
6 |
7 | LegacyPrinter sınıfı eski tür printer makinelerini ifade ediyor olsun. Bu makinelerde
8 | tarama veya fax gönderme gibi fonksiyonellikler bulunmayabilir. Ancak bu fonksiyonellikler IPrinter
9 | arayüzünde tanımlandıklarından mecburen LegacyPrinter sınıfı tarafından da ele alınmalıdır.
10 | */
11 | public interface IPrinterMachine
12 | {
13 | void Print();
14 | void ScanDocument();
15 | void SendFax();
16 | }
17 |
18 | public class LegacyPrinter
19 | : IPrinterMachine
20 | {
21 | public void Print()
22 | {
23 | }
24 | public void ScanDocument()
25 | {
26 | }
27 | public void SendFax()
28 | {
29 | }
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/FreeZone/Learning.SOLID/Basics/ISP/GoodPractice.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.SOLID.Basics.ISP;
2 |
3 | public interface IPrinter
4 | {
5 | void Print();
6 | }
7 |
8 | public interface IScanner
9 | {
10 | void ScanDocument();
11 | }
12 |
13 | public interface IFax
14 | {
15 | void SendFax();
16 | }
17 |
18 | public class BasicPrinter : IPrinter
19 | {
20 | public void Print()
21 | {
22 | }
23 | }
24 |
25 | public class SmartPrinter : IPrinter, IScanner
26 | {
27 | public void Print()
28 | {
29 | }
30 |
31 | public void ScanDocument()
32 | {
33 | }
34 | }
35 |
36 | public class OfficePrinter : IPrinter, IScanner, IFax
37 | {
38 | public void Print()
39 | {
40 | }
41 |
42 | public void ScanDocument()
43 | {
44 | }
45 |
46 | public void SendFax()
47 | {
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/FreeZone/Learning.SOLID/Basics/LSP/BadPractice.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.SOLID.Basics.LSP;
2 |
3 | /*
4 | LSP,türetilmiş sınıfların türediği taban sınıf yerine kullanılabilir olmasını savunur.
5 | Aşağıdaki senaryoda Payment isimli base class diğer ödeme yöntemleri için uygun olmayan davranışları içermekte.
6 | Örneğin, CreditCardPayment sınıfı kredi kartı ödemesi ile ilgili davranışları devralırken CashPayment
7 | sınıfı da kredi kartı bilgilerinin doğrulanması gibi gereksiz metotları devralıyor. Yani türeyen sınıf esasında türediği base class yerine kullanılamıyor.
8 | Öyle ki CashPayment sınıfı ile çalışan bir object user taban sınıftan gelen gereksiz metotlarla uğraşmak zorunda kalmakta.
9 | */
10 | public class Payment
11 | {
12 | public virtual void ValidateCardDetails(string cardNumber, string expiryDate, string cvv)
13 | {
14 | }
15 |
16 | public virtual void ProcessPayment(decimal amount)
17 | {
18 | }
19 | }
20 |
21 | public class CreditCardPayment : Payment
22 | {
23 | public override void ValidateCardDetails(string cardNumber, string expiryDate, string cvv)
24 | {
25 | }
26 |
27 | public override void ProcessPayment(decimal amount)
28 | {
29 | }
30 | }
31 |
32 | public class CashPayment : Payment
33 | {
34 | public override void ValidateCardDetails(string cardNumber, string expiryDate, string cvv)
35 | {
36 | // Bu ödeme türünde kart bilgilerini ele almak tamamen gereksiz
37 | throw new NotImplementedException();
38 | }
39 |
40 | public override void ProcessPayment(decimal amount)
41 | {
42 | }
43 | }
44 |
45 |
46 |
--------------------------------------------------------------------------------
/FreeZone/Learning.SOLID/Basics/LSP/GoodPractice.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.SOLID.Basics.LSP;
2 |
3 | public interface IPayment
4 | {
5 | void ProcessPayment(decimal amount);
6 | }
7 |
8 | public class CreditCardPaymentProvider : IPayment
9 | {
10 | public void ValidateCardDetails(string cardNumber, string expiryDate, string cvv)
11 | {
12 | }
13 |
14 | public void ProcessPayment(decimal amount)
15 | {
16 | }
17 | }
18 |
19 | public class CashPaymentProvider : IPayment
20 | {
21 | public void ProcessPayment(decimal amount)
22 | {
23 | }
24 | }
25 |
26 | public class PaymentProcessor
27 | {
28 | public void Process(IPayment payment, decimal amount)
29 | {
30 | payment.ProcessPayment(amount);
31 | }
32 | }
33 |
34 | public class Application
35 | {
36 | public static void Run()
37 | {
38 | IPayment creditCardPayment = new CreditCardPaymentProvider();
39 | IPayment cashPayment = new CashPaymentProvider();
40 |
41 | PaymentProcessor processor = new();
42 |
43 | processor.Process(creditCardPayment, 1000);
44 | processor.Process(cashPayment, 1500);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/FreeZone/Learning.SOLID/Basics/OCP/BadPractice.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.SOLID.Basics.OCP;
2 |
3 | /*
4 | Tipe göre indirim oranını hesaplayan aşağıdaki sınıfa yeni bir tip dahil etmek istersek
5 | kodunu değiştirmemiz gerekir.
6 | */
7 | public class DiscountManager
8 | {
9 | public double Calculate(double amount, string type)
10 | {
11 | if (type == "Employee")
12 | {
13 | return amount * 0.3;
14 | }
15 | if (type == "Student")
16 | {
17 | return amount * 0.7;
18 | }
19 | return amount;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FreeZone/Learning.SOLID/Basics/OCP/GoodPractice.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.SOLID.Basics.OCP;
2 |
3 | /*
4 | İndirim hesaplaması yapan davranış bir arayüz ile soyutlanmıştır
5 | Buna göre Çalışan ve Öğrenci için bu stratejiler istenildiği gibi yazılabilir ve DiscountProvider tarafından kullanılabilir.
6 | Söz gelimi Student ve Employee dışında farklı bir koşula göre indirim alabilecek Veteran'ların da sisteme dahil edildiğini düşünelim.
7 | Normalde DiscountManager sınıfında yeni bir if bloğu açmamız ve kodu değiştirmemiz gerekecekti.
8 |
9 | */
10 | public interface IDiscountStrategy
11 | {
12 | decimal Apply(double amount);
13 | }
14 |
15 | public class EmployeeDiscount : IDiscountStrategy
16 | {
17 | public decimal Apply(double amount)
18 | {
19 | return (decimal)(amount * 0.3);
20 | }
21 | }
22 |
23 | public class StudentDiscount : IDiscountStrategy
24 | {
25 | public decimal Apply(double amount)
26 | {
27 | return (decimal)(amount * 0.7);
28 | }
29 | }
30 |
31 | public class VeteranDiscount : IDiscountStrategy
32 | {
33 | public decimal Apply(double amount)
34 | {
35 | return (decimal)(amount * 0.9);
36 | }
37 | }
38 |
39 | public class DiscountProvider
40 | {
41 | public static decimal Calculate(double amount, IDiscountStrategy strategy)
42 | {
43 | return strategy.Apply(amount);
44 | }
45 | }
46 |
47 | public class Application
48 | {
49 | public static void Run()
50 | {
51 | IDiscountStrategy discountStrategy = new VeteranDiscount();
52 | DiscountProvider.Calculate(1000, discountStrategy);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/FreeZone/Learning.SOLID/Basics/SRP/BadPractice.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.SOLID.Basics.SRP;
2 |
3 | /*
4 | FreeInvoice isimli sınıf birden fazla görev içermekte.
5 | */
6 | public class FreeInvoice
7 | {
8 | public void CalculateTotal()
9 | {
10 |
11 | }
12 | public void SaveToRepository()
13 | {
14 |
15 | }
16 | public void Print()
17 | {
18 |
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/FreeZone/Learning.SOLID/Basics/SRP/GoodPractice.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.SOLID.Basics.SRP;
2 |
3 | /*
4 | Fatura türü ile ilgili olan görevler uygun sınıflara ayrılmış vaziyette.
5 | Her sınıf tek bir sorumluluğa sahiptir.
6 | Invoice sadece fatura tutarı hesaplar, InvoiceRepository bir veritabanı ya da farklı bir ortama
7 | kaydetme işini üstlenir, InvoicePrinter ise faturayı yazdırma işini.
8 | */
9 | public class Invoice
10 | {
11 | public void CalculateTotal()
12 | {
13 |
14 | }
15 | }
16 |
17 | public class InvoiceRepository
18 | {
19 | public void Save(Invoice invoice)
20 | {
21 |
22 | }
23 | }
24 |
25 | public class InvoicePrinter
26 | {
27 | public void Print(Invoice invoice)
28 | {
29 |
30 | }
31 | }
32 |
33 | public class InvoiceConverter
34 | {
35 | public void ConvertToPdf(Invoice invoice)
36 | {
37 |
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/FreeZone/Learning.SOLID/Learning.SOLID.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/FreeZone/Learning.SOLID/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.SOLID
2 | {
3 | internal class Program
4 | {
5 | static void Main(string[] args)
6 | {
7 | Console.WriteLine("Hello, World!");
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Structs.Client/Learning.Structs.Client.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Structs.Client/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Structs.Client
2 | {
3 | internal class Program
4 | {
5 | static void Main()
6 | {
7 | var cmpx_1 = new ComplexNumber(1.2f, -3.4f);
8 | Console.WriteLine(cmpx_1);
9 | var cmpx_2 = cmpx_1.Add(new ComplexNumber(3.4f, 1.0f));
10 | Console.WriteLine(cmpx_2);
11 |
12 | var rectangle = new Square(10, 20);
13 | Console.WriteLine("Rectangle area is {0}. Perimeter is {1}", rectangle.GetArea(), rectangle.GetPerimeter());
14 |
15 | var velocity = new Vector2D(3.0, 1.0);
16 | Console.WriteLine($"Vector magnitude ise {velocity.Magnitude()}");
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Structs/ComplexNumber.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Structs
2 | {
3 | public struct ComplexNumber(float real, float imaginary)
4 | {
5 | public float Real { get; set; } = real;
6 | public float Imaginary { get; set; } = imaginary;
7 |
8 | //TODO@buraksenyurt Add ve Multiply operasyonları operator overloading ile karşılanabilir
9 | public ComplexNumber Add(ComplexNumber other)
10 | {
11 | return new ComplexNumber(this.Real + other.Real, this.Imaginary + other.Imaginary);
12 | }
13 |
14 | public ComplexNumber Multiply(ComplexNumber other)
15 | {
16 | return new ComplexNumber(
17 | this.Real * other.Real - this.Imaginary * other.Imaginary,
18 | this.Real * other.Imaginary + this.Imaginary * other.Real
19 | );
20 | }
21 | public override string ToString()
22 | {
23 | return $"{Real:F2} + ({Imaginary})i";
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Structs/Learning.Structs.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Structs/Square.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Structs
2 | {
3 | ///
4 | /// Dörtgenleri temsil eder
5 | ///
6 | public struct Square
7 | {
8 | ///
9 | /// Dörtgen uzunluğu
10 | ///
11 | public double Width { get; set; }
12 | ///
13 | /// Dörtgen yüksekliği
14 | ///
15 | public double Height { get; set; }
16 |
17 | ///
18 | /// Dörtgen nesnesi örnekler
19 | ///
20 | /// En
21 | /// Boy
22 | public Square(double width, double height)
23 | {
24 | Width = width;
25 | Height = height;
26 | }
27 |
28 | ///
29 | /// Dörtgenin alanını hesaplar
30 | ///
31 | /// Alan değeri
32 | public double GetArea()
33 | {
34 | return Width * Height;
35 | }
36 |
37 | ///
38 | /// Dörtgenin çevresini hesaplar
39 | ///
40 | /// Çevre değeri
41 | public double GetPerimeter()
42 | {
43 | return 2 * (Width + Height);
44 | }
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/FreeZone/Learning.Structs/Vector2D.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Structs
2 | {
3 | /*
4 | Aşağıdaki örnekte XML Comment kullanımları da örneklenmiştir.
5 | Vector2D sınıfını kullandığımız yerlerde bu comment'ler IDE tarafından kullanıcıya gösterilen tip box'larda görünür.
6 | Ayrıca XML dokümantasyonu üzerinden kütüphaneler için Help içerikleri de üretilebilir.
7 |
8 | Detaylar için https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/xmldoc/
9 | */
10 |
11 | ///
12 | /// İki boyutlu düzlemde bir vektör nesnesini ifade eder
13 | ///
14 | /// X değeri
15 | /// Y değeri
16 | public struct Vector2D(double x, double y)
17 | {
18 | ///
19 | /// Vektörün X ekseni değeri
20 | ///
21 | public double X { get; set; } = x;
22 | ///
23 | /// Vektörün y ekseni değeri
24 | ///
25 | public double Y { get; set; } = y;
26 |
27 | ///
28 | /// Vektör büyüklüğünü hesaplamak için kullanılan fonksiyondur
29 | ///
30 | /// Vektör büyüklüğü
31 | public double Magnitude()
32 | {
33 | // Math sınıfının statik Karekök alma fonksiyonundan yararlanılmıştır
34 | return Math.Sqrt(X * X + Y * Y);
35 | }
36 |
37 | //TODO@buraksenyurt Operator Overloading konusu ile Add metodunu toplama operasyonuna alalım.
38 |
39 | ///
40 | /// Bir vektöre yeni bir vektör eklemek için kullanılan fonksiyondur
41 | ///
42 | /// Eklenecek vektör
43 | /// Toplama sonrası elde edilen yeni vektördür
44 | public Vector2D Add(Vector2D other)
45 | {
46 | return new Vector2D(this.X + other.X, this.Y + other.Y);
47 | }
48 |
49 | ///
50 | /// Vektörler arası nokta çarpım değerini hesaplar
51 | ///
52 | /// Referans vektör
53 | /// Notka çarpım değeri
54 | public double DotProduct(Vector2D other)
55 | {
56 | return this.X * other.X + this.Y * other.Y;
57 | }
58 |
59 | ///
60 | /// Vektörler arasındaki yön ilişkisini bulmak için kullanılır.
61 | ///
62 | /// Nokta çarpım değeri sıfırdan büyükse aynı yön
63 | /// Nokta çarpım değeri sıfırdan küçükse ters yön
64 | /// Diğer halde birbirlerine dik konumda
65 | ///
66 | ///
67 | /// Referans vektör
68 | /// Yön bilgisi
69 | public Direction GetDirection(Vector2D other)
70 | {
71 | double dotProduct = this.DotProduct(other);
72 |
73 | if (dotProduct > 0)
74 | {
75 | return Direction.SameDirection;
76 | }
77 | else if (dotProduct < 0)
78 | {
79 | return Direction.OppositeDirection;
80 | }
81 | else
82 | {
83 | return Direction.Perpendicular;
84 | }
85 | }
86 | }
87 |
88 | ///
89 | /// Vektörler ile ilgili yön bilgilendirilmesi için kullanılır
90 | ///
91 | public enum Direction
92 | {
93 | SameDirection,
94 | OppositeDirection,
95 | Perpendicular
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/FreeZone/RobotFactory/Factories/IReportGenerator.cs:
--------------------------------------------------------------------------------
1 | using RobotFactory.Models;
2 |
3 | namespace RobotFactory.Factories;
4 |
5 | public interface IReportGenerator
6 | {
7 | void Generate(List robots);
8 | }
9 |
--------------------------------------------------------------------------------
/FreeZone/RobotFactory/Factories/IRobotFactory.cs:
--------------------------------------------------------------------------------
1 | using RobotFactory.Models;
2 |
3 | namespace RobotFactory.Factories;
4 |
5 | public interface IRobotFactory
6 | {
7 | Robot CreateRobot(string type, int productionCode, string name);
8 | }
9 |
--------------------------------------------------------------------------------
/FreeZone/RobotFactory/Factories/RobotFactory.cs:
--------------------------------------------------------------------------------
1 | using RobotFactory.Models;
2 |
3 | namespace RobotFactory.Factories;
4 |
5 | public class RobotFactory
6 | : IRobotFactory
7 | {
8 | public Robot CreateRobot(string type, int productionCode, string name)
9 | {
10 | return type.ToLower() switch
11 | {
12 | "assembly" => new AssemblyRobot(productionCode, name),
13 | "transport" => new TransportRobot(productionCode, name),
14 | "inspection" => new InspectionRobot(productionCode, name),
15 | _ => throw new ArgumentException($"Unknown robot type: {type}")
16 | };
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/FreeZone/RobotFactory/Managers/TaskManager.cs:
--------------------------------------------------------------------------------
1 | using RobotFactory.Factories;
2 | using RobotFactory.Models;
3 | using RobotFactory.Reports;
4 |
5 | namespace RobotFactory.Managers;
6 |
7 | public class TaskManager(IRobotFactory robotFactory, ReportGenerator reportGenerator)
8 | {
9 | private readonly List _robots = [];
10 |
11 | public void AddRobot(string type, int id, string name)
12 | {
13 | var robot = robotFactory.CreateRobot(type, id, name);
14 | _robots.Add(robot);
15 | Console.WriteLine($"{robot.Name} added to task manager.");
16 | }
17 |
18 | public void AssignTaskToRobot(int productionCode, string task)
19 | {
20 | var robot = _robots.FirstOrDefault(r => r.ProductionCode == productionCode);
21 | if (robot == null)
22 | {
23 | Console.WriteLine($"Robot with production code {productionCode} not found.");
24 | return;
25 | }
26 |
27 | robot.AssignTask(task);
28 | }
29 |
30 | public void ExecuteAllTasks()
31 | {
32 | foreach (var robot in _robots)
33 | {
34 | robot.PerformTask();
35 | }
36 | }
37 |
38 | public void GenerateReport()
39 | {
40 | reportGenerator.Generate(_robots);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/FreeZone/RobotFactory/Models/AssemblyRobot.cs:
--------------------------------------------------------------------------------
1 | namespace RobotFactory.Models;
2 |
3 | public class AssemblyRobot(int productionCode, string name)
4 | : Robot(productionCode, name)
5 | {
6 | public override void PerformTask()
7 | {
8 | Console.WriteLine($"{Name} is assembling parts for task: {Task}");
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/FreeZone/RobotFactory/Models/InspectionRobot.cs:
--------------------------------------------------------------------------------
1 | namespace RobotFactory.Models;
2 |
3 | public class InspectionRobot(int productionCode, string name) : Robot(productionCode, name)
4 | {
5 | public override void PerformTask()
6 | {
7 | Console.WriteLine($"{Name} is inspecting quality for task: {Task}");
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/FreeZone/RobotFactory/Models/Robot.cs:
--------------------------------------------------------------------------------
1 | namespace RobotFactory.Models;
2 |
3 | public abstract class Robot(int productionCode, string name)
4 | {
5 | public int ProductionCode { get; } = productionCode;
6 | public string Name { get; } = name;
7 | public string Task { get; private set; } = "Idle";
8 |
9 | public virtual void AssignTask(string task)
10 | {
11 | Task = task;
12 | Console.WriteLine($"{Name} assigned task: {task}");
13 | }
14 |
15 | public abstract void PerformTask();
16 |
17 | public override string ToString()
18 | {
19 | return $"{ProductionCode}-> {Name}, Task: {Task})";
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/FreeZone/RobotFactory/Models/TransportRobot.cs:
--------------------------------------------------------------------------------
1 | namespace RobotFactory.Models;
2 |
3 | public class TransportRobot(int productionCode, string name)
4 | : Robot(productionCode, name)
5 | {
6 | public override void PerformTask()
7 | {
8 | Console.WriteLine($"{Name} is transporting items for task: {Task}");
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/FreeZone/RobotFactory/Program.cs:
--------------------------------------------------------------------------------
1 | using RobotFactory.Managers;
2 | using RobotFactory.Reports;
3 |
4 | namespace RobotFactory;
5 |
6 | internal class Program
7 | {
8 | static void Main()
9 | {
10 | var factory = new Factories.RobotFactory();
11 | var reporter = new ReportGenerator();
12 | var taskManager = new TaskManager(factory, reporter);
13 |
14 | taskManager.AddRobot("assembly", 1, "Assembler-1");
15 | taskManager.AddRobot("transport", 2, "Transporter-1");
16 | taskManager.AddRobot("inspection", 3, "Inspector-1");
17 |
18 | taskManager.AssignTaskToRobot(1, "Assemble an another robot");
19 | taskManager.AssignTaskToRobot(2, "Transport neccessary materials");
20 | taskManager.AssignTaskToRobot(3, "Inspect robot quality");
21 |
22 | taskManager.ExecuteAllTasks();
23 | taskManager.GenerateReport();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/FreeZone/RobotFactory/Reports/ReportGenerator.cs:
--------------------------------------------------------------------------------
1 | using RobotFactory.Factories;
2 | using RobotFactory.Models;
3 |
4 | namespace RobotFactory.Reports;
5 |
6 | public class ReportGenerator
7 | :IReportGenerator
8 | {
9 | public void Generate(List robots)
10 | {
11 | Console.WriteLine("********************");
12 | Console.WriteLine("* Factory Report *");
13 | Console.WriteLine("********************");
14 |
15 | foreach (var robot in robots)
16 | {
17 | Console.WriteLine(robot);
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/FreeZone/RobotFactory/RobotFactory.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Burak Selim Senyurt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Learning.Delegates/BasicSample.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Delegates;
2 |
3 | delegate int MathOperation(int a, int b);
4 |
5 | class BasicSample
6 | {
7 | public static void Run()
8 | {
9 | MathOperation addition = (a, b) => a + b;
10 | // static int addition(int a, int b) => a + b; // Local Function kullanımı
11 | MathOperation subtraction = (a, b) => a - b;
12 |
13 | int x = 5;
14 | int y = 9;
15 |
16 | MathOperation operation = addition;
17 | Console.WriteLine($"Result: {operation(x, y)}");
18 | MathOperation operation1 = subtraction;
19 | Console.WriteLine($"Result: {operation(x, y)}");
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Learning.Delegates/EventSample.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Delegates;
2 |
3 | delegate void OrderProcessedHandler(string orderId);
4 |
5 | class OrderProcessor
6 | {
7 | public event OrderProcessedHandler OrderProcessed;
8 |
9 | public void ProcessOrder(string orderId)
10 | {
11 | Console.WriteLine($"Order {orderId} is being processed...");
12 | System.Threading.Thread.Sleep(1000);
13 | Console.WriteLine($"Order {orderId} processed!");
14 |
15 | OrderProcessed?.Invoke(orderId);
16 | }
17 | }
18 |
19 | class EventSample
20 | {
21 | public static void Run()
22 | {
23 | var processor = new OrderProcessor();
24 |
25 | processor.OrderProcessed += orderId => Console.WriteLine($"Email sent for order {orderId}");
26 | processor.OrderProcessed += orderId => Console.WriteLine($"Data Warehouse notified for order {orderId}");
27 |
28 | Console.WriteLine("Enter order ID:");
29 | string orderId = Console.ReadLine();
30 |
31 | processor.ProcessOrder(orderId);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Learning.Delegates/Learning.Delegates.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Learning.Delegates/MulticastSample.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Delegates;
2 |
3 | /*
4 | Multicast Delegate; Bir delegate ile birden fazla metodu zincir olarak bağlayıp kullanmamız mümkündür.
5 | Tek bir delegate çağrısı kendisine += operatörü ile eklenmiş tüm metotların çağırılması anlamına gelir
6 |
7 | Event; Delegate tipleri ile event'lerin tetiklenmesi de mümkündür.
8 | */
9 |
10 | delegate void LogHandler(string message);
11 |
12 | static class MulticastSample
13 | {
14 | public static void Run()
15 | {
16 | #region Multicast Delegate Kullanımı
17 |
18 | // Aşağıdaki satırda handlers isimli değişkene LogToConsole metodunu atadık
19 | LogHandler handlers = LogToConsole;
20 | handlers += LogToTextFile; // handlers değişkenine ikinci bir metot daha ekledik
21 | handlers += LogToDatabase;
22 | Log(handlers, "API gateway online");
23 |
24 | //handlers("Connection succedded..."); // Hem Console, hem text hem de db loglama fonksiyonları arka arkaya çağrılır
25 |
26 | // handlers -= LogToTextFile;
27 |
28 | //handlers("Loading games...");
29 |
30 | #endregion
31 | }
32 | static void Log(LogHandler handler, string message)
33 | {
34 | handler(message);
35 | }
36 |
37 | static void LogToConsole(string message)
38 | {
39 | Console.WriteLine($"{DateTime.Now}: {message}");
40 | }
41 | static void LogToTextFile(string message)
42 | {
43 | var logText = $"\n{DateTime.Now}: {message}";
44 | File.AppendAllText(Path.Combine(Environment.CurrentDirectory, "logs.txt"), logText);
45 | }
46 | static void LogToDatabase(string message)
47 | {
48 | Console.WriteLine("Writing to db");
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Learning.Delegates/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Learning.Delegates;
2 |
3 | /*
4 | Delegate tipi ile metotları işaret edebiliriz. Bu metotları parametre olarak başla metotlara
5 | taşıyabilmebizi, zincir metot dizilimleri oluşturabilmemizi, belli durumlarda çalışma zamanında
6 | event tetiklenmesini sağlar. LINQ sorgularında kullanılan birçok genişletme metodu(extension method)
7 | Func, Predicate vb delegate türlerini kullanır.
8 |
9 | Bu projede örnek delegate kullanımlarına yer verilmiştir.
10 | */
11 | internal class Program
12 | {
13 | static void Main(string[] args)
14 | {
15 | BasicSample.Run();
16 | MulticastSample.Run();
17 | EventSample.Run();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Practices/Orange/O01/CsvWriter.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 |
3 | namespace O01;
4 |
5 | public class CsvWriter(string fileName = "GameState.dat")
6 | : IPersistance
7 | {
8 | private string FileName { get; } = fileName;
9 |
10 | public void Save(List entities)
11 | {
12 | var builder = new StringBuilder();
13 |
14 | foreach (var entity in entities)
15 | {
16 | builder.AppendLine(entity.ToString());
17 | }
18 |
19 | File.WriteAllText(Path.Combine(Environment.CurrentDirectory, FileName), builder.ToString());
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Practices/Orange/O01/DatabaseWriter.cs:
--------------------------------------------------------------------------------
1 | namespace O01;
2 |
3 | public class DatabaseWriter
4 | : IPersistance
5 | {
6 | public void Save(List entities)
7 | {
8 | Console.WriteLine("Database save operations");
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Practices/Orange/O01/GameEntity.cs:
--------------------------------------------------------------------------------
1 | namespace O01;
2 |
3 | public class GameEntity
4 | {
5 | public Guid Id { get; private set; } = Guid.NewGuid();
6 | public (double, double) Position { get; set; }
7 |
8 | public override string ToString() => $"{Id}|{Position.Item1}:{Position.Item2}";
9 | }
10 |
--------------------------------------------------------------------------------
/Practices/Orange/O01/GameState.dat:
--------------------------------------------------------------------------------
1 | 10417920-6a94-44fd-a11e-87e9fc7291e6|10:0
2 | 579b3628-8d27-4508-918f-37d06d855749|20:30
3 | 49b4995f-c3c7-4dd1-92a2-26fd976deba1|0:-10
4 |
--------------------------------------------------------------------------------
/Practices/Orange/O01/IPersistance.cs:
--------------------------------------------------------------------------------
1 | namespace O01;
2 |
3 | public interface IPersistance
4 | where T : GameEntity
5 | {
6 | void Save(List entities);
7 | }
8 |
--------------------------------------------------------------------------------
/Practices/Orange/O01/O01.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Practices/Orange/O01/Program.cs:
--------------------------------------------------------------------------------
1 | using O01;
2 |
3 | internal class Program
4 | {
5 | private static void Main()
6 | {
7 | var writer = new CsvWriter();
8 | var world = new World(writer);
9 | world.AddEntities(
10 | new GameEntity { Position = new(10.0, 0.0) }
11 | , new GameEntity { Position = new(20.0, 30.0) }
12 | , new GameEntity { Position = new(0.0, -10.0) }
13 | );
14 |
15 | world.SaveLastState();
16 | }
17 | }
--------------------------------------------------------------------------------
/Practices/Orange/O01/World.cs:
--------------------------------------------------------------------------------
1 | namespace O01;
2 |
3 | public class World(IPersistance persistance)
4 | {
5 | private readonly List _entities = [];
6 | private readonly IPersistance _persistance = persistance;
7 | public void AddEntities(params GameEntity[] entities) => _entities.AddRange(entities);
8 | public void SaveLastState()
9 | {
10 | Console.WriteLine($"Saving for {_entities.Count} objects");
11 | _persistance.Save(_entities);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y00/Book.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Y00;
4 |
5 | public class Book
6 | {
7 | public Guid Id { get; private set; } = Guid.NewGuid();
8 | public string Title { get; set; }
9 | public string Summary { get; set; }
10 | public decimal ListPrice { get; set; }
11 | public Category Category { get; set; }
12 | public Topic[] Topics { get; set; }
13 | }
14 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y00/Category.cs:
--------------------------------------------------------------------------------
1 | namespace Y00;
2 |
3 | public class Category
4 | {
5 | public int Id { get; set; }
6 | public string Name { get; set; }
7 | }
8 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y00/Program.cs:
--------------------------------------------------------------------------------
1 | using Y00;
2 |
3 | internal class Program
4 | {
5 | private static void Main()
6 | {
7 | var novelCategory = new Category
8 | {
9 | Id = 1,
10 | Name = "Novel"
11 | };
12 | var fermatsBook = new Book
13 | {
14 | Title = "Fermat'nın Son Teoremi",
15 | Summary = "Fermat'nın ünlü probleminin çözümüne tarihi bir bakış",
16 | Category = novelCategory,
17 | ListPrice = 9.99M,
18 | Topics = [
19 | new Topic{Name="Tarih"},
20 | new Topic{Name="Matematik"},
21 | new Topic{Name="Herkes Okuyabilir"},
22 | new Topic{Name="Gizem Uyandıran"}
23 | ]
24 | };
25 |
26 | Console.WriteLine("{0} - {1}({2})", fermatsBook.Id, fermatsBook.Title, fermatsBook.ListPrice);
27 | foreach (var topic in fermatsBook.Topics)
28 | {
29 | Console.Write("{0},", topic.Name);
30 | }
31 | Console.WriteLine();
32 | }
33 | }
--------------------------------------------------------------------------------
/Practices/Yellow/Y00/Topic.cs:
--------------------------------------------------------------------------------
1 | namespace Y00;
2 |
3 | public class Topic
4 | {
5 | public string Name { get; set; }
6 | }
7 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y00/Y00.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y01/Program.cs:
--------------------------------------------------------------------------------
1 | using Y01;
2 |
3 | internal class Program
4 | {
5 | private static void Main()
6 | {
7 | Vector2D vector1 = new(2.4, 4.5);
8 | Vector2D vector2 = new(1.2, -2.5);
9 |
10 | Vector2D unitVector = vector1.ToUnitVector();
11 | Console.WriteLine($"{vector1} için birim vektör değeri: {unitVector}");
12 |
13 | double curvature = vector1.Curvature(vector2);
14 | Console.WriteLine($"{vector1} ile {vector2} arası eğim: {curvature} derecedir");
15 | }
16 | }
--------------------------------------------------------------------------------
/Practices/Yellow/Y01/Vector2D.cs:
--------------------------------------------------------------------------------
1 | namespace Y01;
2 |
3 | public struct Vector2D(double x, double y)
4 | {
5 | public double X { get; } = x;
6 | public double Y { get; } = y;
7 |
8 | public double Magnitude() => Math.Sqrt(X * X + Y * Y);
9 |
10 | public Vector2D ToUnitVector()
11 | {
12 | double length = Magnitude();
13 |
14 | if (length == 0)
15 | throw new InvalidOperationException("Zero-length vector cannot be normalized.");
16 |
17 | return new Vector2D(X / length, Y / length);
18 | }
19 |
20 | public double Curvature(Vector2D other)
21 | {
22 | double dotProduct = X * other.X + Y * other.Y;
23 | double magnitudeProduct = Magnitude() * other.Magnitude();
24 | double angle = Math.Acos(dotProduct / magnitudeProduct);
25 |
26 | return angle * (180 / Math.PI);
27 | }
28 |
29 | public override string ToString() => $"({X}, {Y})";
30 | }
31 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y01/Y01.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y02/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Y02;
2 |
3 | class Program
4 | {
5 | static void Main()
6 | {
7 | string characterName = "Batman";
8 | double characterHeight = 1.88;
9 | char gender = 'M';
10 | bool hasSuperPowers = false;
11 | uint age = 35;
12 |
13 | PrintHeroInfo(characterName, characterHeight, gender, hasSuperPowers, age);
14 | }
15 |
16 | static void PrintHeroInfo(string name, double height, char gender, bool hasPowers, uint age)
17 | {
18 | Console.WriteLine($"{name.ToUpper()}");
19 | Console.WriteLine($"Boy: {height} metre");
20 | Console.WriteLine($"Cinsiyeti: {gender}");
21 | Console.WriteLine($"Yaşı: {age}");
22 | Console.WriteLine($"Süper Güçleri Var mı?: {(hasPowers ? "Evet" : "Hayır")}");
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y02/Y02.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y03/HttpStatus.cs:
--------------------------------------------------------------------------------
1 | namespace Y03;
2 |
3 | public enum HttpStatusCode
4 | {
5 | Ok = 200,
6 | Created = 201,
7 | NoContent = 204,
8 | BadRequest = 400,
9 | NotFound = 404,
10 | InternalServerError = 500
11 | }
12 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y03/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Y03;
2 | class Program
3 | {
4 | static void Main()
5 | {
6 | HttpStatusCode[] codes = [
7 | HttpStatusCode.Ok,HttpStatusCode.BadRequest,HttpStatusCode.NoContent
8 | ];
9 |
10 | foreach (var code in codes)
11 | {
12 | Console.WriteLine($"{code}: {GetStatusDescription(code)}");
13 | }
14 | }
15 |
16 | static string GetStatusDescription(HttpStatusCode code)
17 | {
18 | return code switch
19 | {
20 | HttpStatusCode.Ok => "İstek başarıyla tamamlandı.",
21 | HttpStatusCode.Created => "Kaynak başarıyla oluşturuldu.",
22 | HttpStatusCode.NoContent => "İstek başarıyla işlendi fakat içerik yok.",
23 | HttpStatusCode.BadRequest => "İstek geçersiz veya hatalı.",
24 | HttpStatusCode.NotFound => "İstenen kaynak bulunamadı.",
25 | HttpStatusCode.InternalServerError => "Sunucu hatası oluştu.",
26 | _ => "Bilinmeyen durum kodu."
27 | };
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y03/Y03.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y04/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Y04;
2 |
3 | class Program
4 | {
5 | static void Main()
6 | {
7 | var motto = "it's a beautiful day";
8 | var shining_motto = Terminal.WriteBeauty(motto, Style.Underscore);
9 |
10 | Console.WriteLine(shining_motto);
11 | Console.WriteLine(Terminal.WriteBeauty(motto, Style.Spaces));
12 | Console.WriteLine(Terminal.WriteBeauty(motto, Style.Stars));
13 | Console.WriteLine(Terminal.WriteBeauty(motto, Style.Reversed));
14 |
15 | Console.ForegroundColor = ConsoleColor.Cyan;
16 | Console.WriteLine("\nAşağıda ne yazıyor acaba? :D\n");
17 | Console.ResetColor();
18 | for (var i = 0; i < 3; i++)
19 | {
20 | Console.WriteLine(Terminal.WriteBeauty(motto, Style.Surprised));
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y04/Terminal.cs:
--------------------------------------------------------------------------------
1 | namespace Y04;
2 |
3 | public static class Terminal
4 | {
5 | public static string WriteBeauty(string content, Style style)
6 | {
7 | switch (style)
8 | {
9 | case Style.Underscore:
10 | return Underscore(content);
11 | case Style.Stars:
12 | return Stars(content);
13 | case Style.Spaces:
14 | return Spaces(content);
15 | case Style.Reversed:
16 | return Reversed(content);
17 | case Style.Surprised:
18 | return Surprised(content);
19 | default:
20 | return content;
21 | }
22 | }
23 | private static string Underscore(string content)
24 | {
25 | string result = string.Empty;
26 | foreach (char c in content)
27 | {
28 | result += c.ToString() + '_';
29 | }
30 | return result.Remove(result.Length - 1, 1);
31 | }
32 | private static string Stars(string content)
33 | {
34 | string result = string.Empty;
35 | foreach (char c in content)
36 | {
37 | result += c.ToString() + '*';
38 | }
39 | return result.Remove(result.Length - 1, 1);
40 | }
41 | private static string Spaces(string content)
42 | {
43 | string result = string.Empty;
44 | foreach (char c in content)
45 | {
46 | result += c.ToString() + ' ';
47 | }
48 | return result.Remove(result.Length - 1, 1);
49 | }
50 | private static string Reversed(string content)
51 | {
52 | string result = string.Empty;
53 | var reversedContent = content.Reverse();
54 | foreach (var c in reversedContent)
55 | {
56 | result += c.ToString();
57 | }
58 | return result;
59 | }
60 | private static string Surprised(string content)
61 | {
62 | var characters = content.ToCharArray();
63 | var rand = new Random();
64 |
65 | for (int i = characters.Length - 1; i > 0; i--)
66 | {
67 | int j = rand.Next(0, i + 1);
68 | (characters[j], characters[i]) = (characters[i], characters[j]);
69 | }
70 |
71 | return new string(characters);
72 | }
73 | }
74 |
75 | public enum Style
76 | {
77 | Underscore,
78 | Stars,
79 | Spaces,
80 | Reversed,
81 | Surprised
82 | }
83 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y04/Y04.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y06/Behaviors/IDrawable.cs:
--------------------------------------------------------------------------------
1 | namespace Y06.Behaviors;
2 |
3 | public interface IDrawable
4 | {
5 | void Draw();
6 | }
7 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y06/Components/AzonButton.cs:
--------------------------------------------------------------------------------
1 | using Y06.Behaviors;
2 |
3 | namespace Y06.Components;
4 |
5 | public class AzonButton(int id, string text, (double, double) position)
6 | : BaseButton(id, text, position), IDrawable
7 | {
8 | public void Draw()
9 | {
10 | Console.WriteLine("AzonButton için çizim yapılıyor");
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y06/Components/AzonImageButton.cs:
--------------------------------------------------------------------------------
1 | using Y06.Behaviors;
2 |
3 | namespace Y06.Components;
4 |
5 | public class AzonImageButton(int id, string text, (double, double) position, string image)
6 | : BaseButton(id, text, position), IDrawable
7 | {
8 | public string Image { get; set; } = image;
9 |
10 | public void Draw()
11 | {
12 | Console.WriteLine("AzonImageButton için çizim yapılıyor");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y06/Components/AzonRadioButton.cs:
--------------------------------------------------------------------------------
1 | using Y06.Behaviors;
2 |
3 | namespace Y06.Components;
4 |
5 | public class AzonRadioButton(int id, string text, (double, double) position)
6 | : BaseButton(id, text, position), IDrawable
7 | {
8 | private readonly Dictionary options = [];
9 |
10 | public void AddOption(string optionName, string option) => options.Add(optionName, option);
11 |
12 | public void Draw()
13 | {
14 | Console.WriteLine("AzonRadioButton için çizim yapılıyor");
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y06/Components/BaseButton.cs:
--------------------------------------------------------------------------------
1 | namespace Y06.Components;
2 |
3 | public abstract class BaseButton(int id, string text, (double, double) position)
4 | {
5 | protected int ID { get; set; } = id;
6 | protected string? Text { get; set; } = text;
7 | protected (double, double) Position { get; set; } = position;
8 | }
9 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y06/Controllers/DrawController.cs:
--------------------------------------------------------------------------------
1 | using Y06.Behaviors;
2 |
3 | namespace Y06.Controllers;
4 |
5 | public class DrawController
6 | {
7 | public static void DrawAll(IDrawable[] drawables)
8 | {
9 | foreach (var drawable in drawables)
10 | {
11 | drawable.Draw();
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Practices/Yellow/Y06/Program.cs:
--------------------------------------------------------------------------------
1 | using Y06.Behaviors;
2 | using Y06.Components;
3 | using Y06.Controllers;
4 |
5 | internal class Program
6 | {
7 | private static void Main()
8 | {
9 | List buttons = [
10 | new AzonButton(1, "Save", (0, 0)),
11 | new AzonButton(2, "Print", (250, 0)),
12 | new AzonButton(3, "Close", (500, 0)),
13 | new AzonRadioButton(4, "Save Password", (0, 500)),
14 | new AzonImageButton(5,"Profile Picture",(50,50),"photo.png")
15 | ];
16 | DrawController.DrawAll([.. buttons]);
17 | }
18 | }
--------------------------------------------------------------------------------
/Practices/Yellow/Y06/Y06.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------