{"id":51009865,"url":"https://github.com/rashedul-alam46/solid-principles","last_synced_at":"2026-06-21T01:06:36.138Z","repository":{"id":311167481,"uuid":"1042722534","full_name":"rashedul-alam46/solid-principles","owner":"rashedul-alam46","description":"SOLID Principles in C#","archived":false,"fork":false,"pushed_at":"2025-09-19T15:49:53.000Z","size":102,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-01T09:31:57.304Z","etag":null,"topics":["csharp","oop","solid-principles"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rashedul-alam46.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-22T13:21:57.000Z","updated_at":"2025-11-12T11:06:45.000Z","dependencies_parsed_at":"2025-08-22T15:50:24.167Z","dependency_job_id":null,"html_url":"https://github.com/rashedul-alam46/solid-principles","commit_stats":null,"previous_names":["rashedulalam46/solid-principles","rashedul-alam46/solid-principles"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rashedul-alam46/solid-principles","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rashedul-alam46%2Fsolid-principles","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rashedul-alam46%2Fsolid-principles/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rashedul-alam46%2Fsolid-principles/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rashedul-alam46%2Fsolid-principles/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rashedul-alam46","download_url":"https://codeload.github.com/rashedul-alam46/solid-principles/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rashedul-alam46%2Fsolid-principles/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34590324,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","oop","solid-principles"],"created_at":"2026-06-21T01:06:35.362Z","updated_at":"2026-06-21T01:06:36.133Z","avatar_url":"https://github.com/rashedul-alam46.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"SOLID Principales\n\n\n\n\n---\n# 💳 SOLID Principles in C# – Payment Processing Example\n\nThis project demonstrates how to apply the **SOLID principles** in a simple **Payment Processing System** using C#.  \nThe goal is to show how following SOLID makes code **cleaner, maintainable, and extensible**.\n\n---\n\n## 📖 Overview\nThe system processes orders using different payment methods and generates invoices.  \nIt applies all **five SOLID principles**:\n\n1. **Single Responsibility Principle (SRP)**  \n   Each class has one responsibility.  \n   - `OrderRepository` → Saves orders  \n   - `PdfInvoice` / `EmailInvoice` → Generate invoices  \n   - `CheckoutService` → Manages checkout process  \n\n2. **Open/Closed Principle (OCP)**  \n   The system is open for extension but closed for modification.  \n   - New payment methods (e.g., `CreditCardPayment`, `PayPalPayment`, `BitcoinPayment`) can be added without changing existing code.  \n\n3. **Liskov Substitution Principle (LSP)**  \n   Subclasses can replace their parent classes without breaking behavior.  \n   - Any `IPaymentProcessor` (Credit Card, PayPal, Bitcoin) can be used in `CheckoutService`.  \n\n4. **Interface Segregation Principle (ISP)**  \n   Clients are not forced to implement methods they don’t use.  \n   - `IInvoiceGenerator` is separate from `IPaymentProcessor`.  \n\n5. **Dependency Inversion Principle (DIP)**  \n   High-level modules depend on abstractions, not concrete implementations.  \n   - `CheckoutService` depends on `IPaymentProcessor` and `IInvoiceGenerator` interfaces.  \n\n---\n\n## S - Single Responsibility Principle\n```csharp\n// Each class has only one reason to change.\npublic class Order\n{\n    public string OrderId { get; set; }\n    public decimal Amount { get; set; }\n}\n\npublic class OrderRepository\n{\n    public void Save(Order order)\n    {\n        Console.WriteLine($\"Order {order.OrderId} saved to database.\");\n    }\n}\n```\n\n## O - Open/Closed Principle\n```csharp\n// Add new payment methods without modifying existing logic.\npublic interface IPaymentProcessor\n{\n    void ProcessPayment(Order order);\n}\n\npublic class CreditCardPayment : IPaymentProcessor\n{\n    public void ProcessPayment(Order order)\n    {\n        Console.WriteLine($\"Processing Credit Card payment for {order.Amount}\");\n    }\n}\n\npublic class PayPalPayment : IPaymentProcessor\n{\n    public void ProcessPayment(Order order)\n    {\n        Console.WriteLine($\"Processing PayPal payment for {order.Amount}\");\n    }\n}\n```\n## L - Liskov Substitution Principle\n```csharp\n// Subtypes (payment methods) can replace the parent type (IPaymentProcessor).\npublic class BitcoinPayment : IPaymentProcessor\n{\n    public void ProcessPayment(Order order)\n    {\n        Console.WriteLine($\"Processing Bitcoin payment for {order.Amount}\");\n    }\n}\n```\n## I - Interface Segregation Principle\n```csh\n// Instead of one big interface, we separate responsibilities.\n\npublic interface IInvoiceGenerator\n{\n    void GenerateInvoice(Order order);\n}\n\npublic class PdfInvoice : IInvoiceGenerator\n{\n    public void GenerateInvoice(Order order)\n    {\n        Console.WriteLine($\"PDF invoice generated for order {order.OrderId}\");\n    }\n}\n\npublic class EmailInvoice : IInvoiceGenerator\n{\n    public void GenerateInvoice(Order order)\n    {\n        Console.WriteLine($\"Invoice emailed for order {order.OrderId}\");\n    }\n}\n```\n\n## D - Dependency Inversion Principle\n```csharp\n// High-level modules depend on abstractions, not concretions.\n\npublic class CheckoutService\n{\n    private readonly IPaymentProcessor _paymentProcessor;\n    private readonly IInvoiceGenerator _invoiceGenerator;\n    private readonly OrderRepository _orderRepository;\n\n    public CheckoutService(IPaymentProcessor paymentProcessor, IInvoiceGenerator invoiceGenerator, OrderRepository orderRepository)\n    {\n        _paymentProcessor = paymentProcessor;\n        _invoiceGenerator = invoiceGenerator;\n        _orderRepository = orderRepository;\n    }\n\n    public void Checkout(Order order)\n    {\n        _paymentProcessor.ProcessPayment(order);\n        _invoiceGenerator.GenerateInvoice(order);\n        _orderRepository.Save(order);\n    }\n}\n```\n## 🚀 Example Run\n\n```csharp\nOrder order = new Order { OrderId = \"123\", Amount = 100.50m };\n\n// Choose payment and invoice types\nIPaymentProcessor payment = new PayPalPayment();\nIInvoiceGenerator invoice = new PdfInvoice();\n\n// Inject dependencies into CheckoutService\nCheckoutService checkout = new CheckoutService(payment, invoice, new OrderRepository());\n\n// Process checkout\ncheckout.Checkout(order);\n```\n\n## Output\n```csharp\nProcessing PayPal payment for 100.50\nPDF invoice generated for order 123\nOrder 123 saved to database.\n```\n\n## ✅ How SOLID is Applied Here:\n\n- SRP → OrderRepository only saves orders, CheckoutService only manages checkout, Invoice classes only handle invoices.\n- OCP → We can add new payments (e.g., StripePayment) without changing existing classes.\n- LSP → Any payment type (CreditCard, PayPal, Bitcoin) can replace IPaymentProcessor without breaking behavior.\n- ISP → Invoices are split (PdfInvoice, EmailInvoice), not forced into one big interface.\n- DIP → CheckoutService depends on abstractions (IPaymentProcessor, IInvoiceGenerator) instead of concrete classes.\n\n  This way, the system is flexible, testable, and extendable.\n\n## 🔴 Breaking OCP (not open for extension, but modification)\n```csharp\npublic class PaymentProcessor\n{\n    public void ProcessPayment(Order order, string paymentType)\n    {\n        if (paymentType == \"CreditCard\")\n        {\n            Console.WriteLine($\"Processing Credit Card payment for {order.Amount}\");\n        }\n        else if (paymentType == \"PayPal\")\n        {\n            Console.WriteLine($\"Processing PayPal payment for {order.Amount}\");\n        }\n        else if (paymentType == \"Bitcoin\")\n        {\n            Console.WriteLine($\"Processing Bitcoin payment for {order.Amount}\");\n        }\n        // ❌ Every time we add a new payment type (Stripe, ApplePay),\n        // we must MODIFY this class → violates OCP\n    }\n}\n```\nProblem:\n- Adding StripePayment means we must edit PaymentProcessor.\n- The class keeps growing and becomes harder to maintain.\n\n## 🔴 Breaking LSP Example\nHigh chance of introducing bugs while modifying.\n```csharp\npublic interface IPaymentProcessor\n{\n    void ProcessPayment(Order order);\n}\n```\nNow, imagine we create a GiftCardPayment class but force it to implement ProcessPayment, even though gift cards don’t work like normal payments:\n```csharp\npublic class GiftCardPayment : IPaymentProcessor\n{\n    public void ProcessPayment(Order order)\n    {\n        // ❌ GiftCard can’t really process payments like CreditCard/PayPal\n        // So we throw an exception\n        throw new NotSupportedException(\"GiftCard cannot process payment directly.\");\n    }\n}\n\npublic void Checkout(Order order)\n{\n    _paymentProcessor.ProcessPayment(order); // ❌ Will crash if GiftCardPayment is used\n}\n```\nWhy this breaks LSP?\n- LSP rule: Subclasses (or implementations) must be usable anywhere the base type is expected.\n- Here, if we substitute GiftCardPayment for IPaymentProcessor, it throws an exception instead of behaving properly.\n- Client code (CheckoutService) now has to know special cases → violates LSP.\n\n✅ Fixing LSP\n\nInstead of forcing GiftCardPayment into the wrong interface, we restructure abstractions:\n```csharp\npublic interface IPaymentProcessor\n{\n    void ProcessPayment(Order order);\n}\n\npublic interface IGiftCardRedemption\n{\n    void RedeemGiftCard(Order order);\n}\n\npublic class CreditCardPayment : IPaymentProcessor\n{\n    public void ProcessPayment(Order order)\n    {\n        Console.WriteLine($\"Processing Credit Card payment for {order.Amount}\");\n    }\n}\n\npublic class PayPalPayment : IPaymentProcessor\n{\n    public void ProcessPayment(Order order)\n    {\n        Console.WriteLine($\"Processing PayPal payment for {order.Amount}\");\n    }\n}\n\npublic class GiftCardRedemption : IGiftCardRedemption\n{\n    public void RedeemGiftCard(Order order)\n    {\n        Console.WriteLine($\"Redeeming gift card for {order.Amount}\");\n    }\n}\n```\n✅ Why this respects LSP?\n- Each implementation behaves correctly without throwing exceptions.\n- GiftCardRedemption is no longer pretending to be a normal payment processor.\n- Substitution works: anywhere you expect IPaymentProcessor, you can safely use CreditCardPayment or PayPalPayment without breaking behavior.\n\n##  🔴 Breaking ISP\n\nSuppose we design one fat interface that tries to handle every possible invoice format:\n\n```csharp\npublic interface IInvoiceGenerator\n{\n    void GeneratePdfInvoice(Order order);\n    void GenerateEmailInvoice(Order order);\n    void GenerateExcelInvoice(Order order);\n}\n```\n\nNow, classes are forced to implement methods they don’t need:\n\n```csharp\npublic class PdfInvoiceGenerator : IInvoiceGenerator\n{\n    public void GeneratePdfInvoice(Order order)\n    {\n        Console.WriteLine($\"PDF invoice generated for order {order.OrderId}\");\n    }\n\n    public void GenerateEmailInvoice(Order order)\n    {\n        // ❌ Not applicable → forced to implement\n        throw new NotImplementedException();\n    }\n\n    public void GenerateExcelInvoice(Order order)\n    {\n        // ❌ Not applicable → forced to implement\n        throw new NotImplementedException();\n    }\n}\n```\n🚨 Why this breaks ISP?\n\n- Classes should not be forced to depend on methods they don’t use.\n- Here, PdfInvoiceGenerator only cares about PDF, but is forced to implement email and Excel too.\n- Any change in IInvoiceGenerator impacts all implementations unnecessarily.\n\n- ✅ Fixing ISP\n\nSplit the interface into smaller, more specific interfaces:\n\n```csharp\npublic interface IPdfInvoiceGenerator\n{\n    void GeneratePdfInvoice(Order order);\n}\n\npublic interface IEmailInvoiceGenerator\n{\n    void GenerateEmailInvoice(Order order);\n}\n\npublic interface IExcelInvoiceGenerator\n{\n    void GenerateExcelInvoice(Order order);\n}\n```\nNow, each implementation only does what it should:\n\n```csharp\npublic class PdfInvoiceGenerator : IPdfInvoiceGenerator\n{\n    public void GeneratePdfInvoice(Order order)\n    {\n        Console.WriteLine($\"PDF invoice generated for order {order.OrderId}\");\n    }\n}\n\npublic class EmailInvoiceGenerator : IEmailInvoiceGenerator\n{\n    public void GenerateEmailInvoice(Order order)\n    {\n        Console.WriteLine($\"Invoice emailed for order {order.OrderId}\");\n    }\n}\n```\n\n✅ Why this respects ISP?\n\n-  Each class depends only on what it really needs.\n- No unnecessary throw new NotImplementedException().\n- Easier to maintain and extend.\n\n\n## 🔴 Breaking DIP\nCheckoutService does depend on abstractions (IPaymentProcessor, IInvoiceGenerator), which is good (follows DIP).\nIf it did not depend on abstractions, it would look like this (bad example ❌):\n\n```csharp\npublic class CheckoutService\n{\n    private readonly CreditCardPayment _creditCardPayment;\n    private readonly PdfInvoice _pdfInvoice;\n    private readonly OrderRepository _orderRepository;\n\n    public CheckoutService()\n    {\n        // Directly instantiating concrete classes (bad practice)\n        _creditCardPayment = new CreditCardPayment();\n        _pdfInvoice = new PdfInvoice();\n        _orderRepository = new OrderRepository();\n    }\n\n    public void Checkout(Order order)\n    {\n        _creditCardPayment.ProcessPayment(order);\n        _pdfInvoice.GenerateInvoice(order);\n        _orderRepository.Save(order);\n    }\n}\n```\n\n🚨 What’s wrong here?\n\n- Tight coupling → CheckoutService is locked to CreditCardPayment and PdfInvoice.\n- No flexibility → If we want to switch to PayPalPayment or EmailInvoice, we must modify CheckoutService.\n- Hard to test → Can’t mock dependencies easily in unit tests.\n\n✅ Why this version is better:\n- Depends on interfaces (abstractions).\n- Easy to swap different implementations without modifying CheckoutService.\n- Easy to test with mocks.\n\n ```csharp\npublic CheckoutService(IPaymentProcessor paymentProcessor, IInvoiceGenerator invoiceGenerator, OrderRepository orderRepository)\n```\n\nSo the difference is:\n- Without DIP → CheckoutService creates and depends on concrete classes.\n- With DIP → CheckoutService depends on interfaces/abstractions provided from outside (injected).\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frashedul-alam46%2Fsolid-principles","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frashedul-alam46%2Fsolid-principles","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frashedul-alam46%2Fsolid-principles/lists"}