├── .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 | --------------------------------------------------------------------------------