# SOLID
- Mục tiêu: Đảm bảo khả năng bảo trì, mở rộng của việc phát triển ứng dụng
- Vì đây là vấn đề mindset nên Q cố gắng ko đưa code vào nên mọi người thông cảm. Q viết chủ yếu dựa trên hiểu biết bản thân và cũng cố gắng tuân theo (có khi không theo XD) nên cũng không cần qua gắt gao trong việc follow chuẩn SOLID nhé
## 1. Single Responsibility Principle
- Bất cứ thứ gì sinh ra trong code được gói trọn trong class, method, biến hay rộng hơn là module thì chỉ nên có 1 lí do tồn tại duy nhất. Hay nói dễ hiểu hơn là chỉ phụ trách một chức năng or mảng nghiệp vụ nào đó cụ thể
- Cực kì hạn chế các trường hợp như Tạo mới, Cập nhật, Xóa trong cùng 1 method mà không có sự phân tách rõ ràng giữa các action
- Bad
```csharp
public bool CreateOrUpdate(List<InputDataDto> data)
{
// get create input dtos
// create new
// get update input dtos
// update exist entities
return true;
}
```
- Good
```csharp
public bool Create(List<CreateInputDto> data){
// get create input dtos
// create new
return true;
}
public bool Update(List<UpdateInputDto> data){
// get update input dtos
// update exist entities
return true
}
```
- Một chút ám ảnh cưỡng chế (ko khuyến khích bắt chước): Phân tách tất cả mọi thứ để đảm bảo khi bạn thay đổi thì chỉ có duy nhất 1 lí do thay đổi và 1 business duy nhất bị ảnh hưởng bởi sự thay đổi đó, đôi khi sẽ dẫn đến việc duplicate code

## 2. Open Closed Principle
- Method, class hay module trong vòng đời phát triển thì sẽ trải bao qua các lần thay đổi, sự thay đổi có thể đến từ nhiều yếu tố. Vì vậy, implementation phải đảm bảo cho sự thay đổi ko ảnh hưởng đến tính đúng đắn của chương trình, cũng như cho phép việc thay đổi là khả thi
- Ví dụ, class Polygon là 1 class abstract, logic SetPoints, GetPoints sẽ được đóng kín (closed) để đảm bảo tính đúng đắn, tuy nhiên method Area() để tính diện tích thì được định nghĩa dưới dạng abstract, cho phép các class kế thừa có thể override (open).
```csharp
public class Point
{
public string Name { get; set; }
}
public abstract class Polygon
{
private ICollection<Point> _points;
public void SetPoints(ICollection<Point> points)
{
_points = points;
}
public ICollection<Point> GetPoints(){
return _points;
}
public abstract double Area();
}
public class Rectangle : Polygon
{
public double Width { get; set; }
public double Height { get; set; }
public override double Area()
{
return Width*Height;
}
}
```
- Ví dụ: việc access data thông qua các ORM cũng tuân thủ Open closed principles, bạn sẽ có N cách để access, query data,... nhưng việc modification như create, update, delete sẽ rất hạn chế, cần nhiều validation trước khi thực thi
-> **Tăng cường khả năng mở rộng, Ràng buộc khả năng chỉnh sửa**

## 3. Liskov Substitution Principle
- Tính kế thừa trong OOP sẽ được đề cập đến với việc các child instance khi kế thừa parent instance thì **phải** làm đc những gì mà parent làm (thay thế parent), cũng như có thể làm thêm những thứ khác (nếu không làm thêm đc gì thì tại sao đẻ ra child instance)

- Ví dụ, class Child có thể thay thế Parent trong việc make coffee, ngoài ra còn có thể làm thêm milkshake
```csharp
public class Parent
{
public void MakeCoffee()
{
Console.WriteLine("Coffee is done!");
}
}
public class Child : Parent
{
public void MakeMilkShake()
{
Console.WriteLine("Milkshake is done");
}
}
public class Test
{
public void GetBeverage()
{
var parent = new Parent();
parent.MakeCoffee(); // <-- Parent can only make coffee
var child = new Child(); // <-- Child can also make coffee and milkshake
child.MakeCoffee();
child.MakeMilkShake();
}
}
```
## 4. Interface Segregation Principle
- Interface một khi định nghĩa và kế thừa thì các class implementation kế thừa chúng phải tuyệt đối implement cho tất cả các method mà được define trong interface
```csharp
public interface IWibuLife {
void Eat();
void Sleep();
void AnimeTime();
}
public class DuyChuLife: IWibuLife{
public void Eat(){
Console.WriteLine("Eat");
}
public void Sleep(){
Console.WriteLine("Sleep");
}
public void AnimeTime(){
// throw new NotImplementedException() // <-- Không đúng, nếu ko có AnimeTime() thì sao là wibu
Console.WriteLine("Anime time !");
}
}
```
- Hạn chế mấy vụ kế thừa interface xong throw NotImplementedException nhé

## 5. Dependency Inversion Principle
- Thay vì phải tạo N con robot với N chức năng khác nhau thì chỉ cần 1 con robot duy nhất với N cánh tay robot theo từng loại chức năng. Để làm đc điều này, cẳng tay robot phải có 1 interface sao cho các cánh tay có thể dễ dàng tháo lắp.
- Vì vậy hãy luôn làm việc với lớp abstraction thay vì implementation. Giải thích một chút về abstraction và implementation
- Abstraction: Dịch ra là trừu tượng hóa, theo từ điển tiếng việt trừu tượng có nghĩa "có được sự khái quát hoá trong tư duy, trên cơ sở dựa vào các thuộc tính, các quan hệ của sự vật; phân biệt với cụ thể" -> Làm việc với lớp abstraction nghĩa là Dev khi code, có sử dụng các class business nào đó để thực thi công việc thì chỉ gọi ra interface của class đó, vốn interface chỉ diễn đạt rằng class implement nó làm chức năng gì, nhận input gì và cho ra output gì.
- Implementation: Dịch ra là sự thực hiện, sẽ là phần thực hiện cho abstraction kể trên. Trong class implementation này sẽ là phần thực thi tuân thủ tuyệt đối lớp abstraction
```diagram
PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSI0MjFweCIgaGVpZ2h0PSIyMjFweCIgdmlld0JveD0iLTAuNSAtMC41IDQyMSAyMjEiIGNvbnRlbnQ9IiZsdDtteGZpbGUgaG9zdD0mcXVvdDtlbWJlZC5kaWFncmFtcy5uZXQmcXVvdDsgbW9kaWZpZWQ9JnF1b3Q7MjAyMi0wNi0wOVQwMzowNToyNy40MzlaJnF1b3Q7IGFnZW50PSZxdW90OzUuMCAoV2luZG93cyBOVCAxMC4wOyBXaW42NDsgeDY0KSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvMTAyLjAuNTAwNS42MyBTYWZhcmkvNTM3LjM2JnF1b3Q7IHZlcnNpb249JnF1b3Q7MTkuMC4zJnF1b3Q7IGV0YWc9JnF1b3Q7LUloVVVCVVdzWHhGNy12bmI4X04mcXVvdDsgdHlwZT0mcXVvdDtlbWJlZCZxdW90OyZndDsmbHQ7ZGlhZ3JhbSBpZD0mcXVvdDs1bFI1eldNTl8waThuamRyUGxBbyZxdW90OyBuYW1lPSZxdW90O1BhZ2UtMSZxdW90OyZndDs1VmRkYjVzd0ZQMDF2RTU4aERROFFraTNhWnRVS1pQV1BqcHdDOVlNUnNZa1pMOStkckREaDRsVXRjbFdiUklQdnNkZjErZmNZd3ZMV3hmdFI0YXEvQnROZ1ZpdW5iYVdGMXV1Nnl4YzE1S2ZuUjQ3Wk9XdU9pQmpPRldEZW1DTGY0RUNiWVUyT0lWNk5KQlRTaml1eG1CQ3l4SVNQc0lRWS9Rd0h2Wk15WGpYQ21WZ0FOc0VFUlA5Z1ZPZTYxUGM5Zmdud0ZtdWQzYVdRZGRUSUQxWW5hVE9VVW9QQThqYldONmFVY3E3VnRHdWdVanlOQy9kdlBzTHZlZkVHSlQ4SlJPVUVIdEVHblcyY0ZkemhoS09hYWxTNUVkOWJrYWJNZ1U1MWJHODZKQmpEdHNLSmJMM0lKUVdXTTRMb3JyVnlzQTR0QmV6Yzg1bkZzVUN0QURPam1LSW5xQnBVblhpTGxWODZGbDNmSVhsQThZWENrTks2T3k4ZE0rRmFDZzY1cW54REdvK0Z4V0JRdVNPM2dVN1h2QVgyVmtZN0JoOFFKbUcwbXdpU2dpcWE1eU1LZWo1c2tVRUxlYVBxa2UybnlUK3dWZFIzQTZHeFVjZGxDTHJ4MkV3bUNYRGZ0b3Awdk82VkNFMVhENmhYaHlITml5QmtWYzRZaG53UVkyWUFnMEVtT05mWXd5SXFLVDlPSWs1VWRRT0R4U0w5Qzdxdi9BbnVuYkpxMW5EUzJDeTBHSXhXY2llTE5RZDJWam9WQ1BuWTcrb2JIeWpiR0xZRzVVamJzVktOcHVDaEFtblRFZ21uWUxGRGZ3VjdZQTgwQnFmTE9qRk84bzVMUVlEUW9JejJjSHB4SEcwNFFTWHNENi9DZmFWTHFuVm1EM0hObTNvelZUQjhnb3VYTjdLaGIzem5vYkdtM1hoRzl6MGJxemp2ZEk2VHVDUHhROXVacDA3UStzdjFzYXhvdENLN3VXMWxKK2l5QW9qWkJTQnFHNCtsbDA4OHZTbk1BT1I3b3BMV29xUjBUTW1aQUloWmFkRWFBbHN4bWNGVGxPNXpleUROeTZ1SzVqTm5iNTV2bW0yNVV6ZFRQVjlqZGxXaGdEZk5lZVJrNXdrd1A4Ujg4R2ZZejR3bU4vcVlvL2xiNFFPL0RMN2h3V3dKd0k0TnhOQWhQMHZTSGRWOVQ5eTN1WTMmbHQ7L2RpYWdyYW0mZ3Q7Jmx0Oy9teGZpbGUmZ3Q7Ij48ZGVmcy8+PGc+PHJlY3QgeD0iMCIgeT0iMTYwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjQwIiByeD0iNiIgcnk9IjYiIGZpbGw9InJnYigyNTUsIDI1NSwgMjU1KSIgc3Ryb2tlPSJyZ2IoMCwgMCwgMCkiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMC41IC0wLjUpIj48c3dpdGNoPjxmb3JlaWduT2JqZWN0IHBvaW50ZXItZXZlbnRzPSJub25lIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiByZXF1aXJlZEZlYXR1cmVzPSJodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9mZWF0dXJlI0V4dGVuc2liaWxpdHkiIHN0eWxlPSJvdmVyZmxvdzogdmlzaWJsZTsgdGV4dC1hbGlnbjogbGVmdDsiPjxkaXYgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHN0eWxlPSJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogdW5zYWZlIGNlbnRlcjsganVzdGlmeS1jb250ZW50OiB1bnNhZmUgY2VudGVyOyB3aWR0aDogMTQ4cHg7IGhlaWdodDogMXB4OyBwYWRkaW5nLXRvcDogMTgwcHg7IG1hcmdpbi1sZWZ0OiAxcHg7Ij48ZGl2IGRhdGEtZHJhd2lvLWNvbG9ycz0iY29sb3I6IHJnYigwLCAwLCAwKTsgIiBzdHlsZT0iYm94LXNpemluZzogYm9yZGVyLWJveDsgZm9udC1zaXplOiAwcHg7IHRleHQtYWxpZ246IGNlbnRlcjsiPjxkaXYgc3R5bGU9ImRpc3BsYXk6IGlubGluZS1ibG9jazsgZm9udC1zaXplOiAxMnB4OyBmb250LWZhbWlseTogSGVsdmV0aWNhOyBjb2xvcjogcmdiKDAsIDAsIDApOyBsaW5lLWhlaWdodDogMS4yOyBwb2ludGVyLWV2ZW50czogYWxsOyB3aGl0ZS1zcGFjZTogbm9ybWFsOyBvdmVyZmxvdy13cmFwOiBub3JtYWw7Ij5BYnN0cmFjdGlvbjwvZGl2PjwvZGl2PjwvZGl2PjwvZm9yZWlnbk9iamVjdD48dGV4dCB4PSI3NSIgeT0iMTg0IiBmaWxsPSJyZ2IoMCwgMCwgMCkiIGZvbnQtZmFtaWx5PSJIZWx2ZXRpY2EiIGZvbnQtc2l6ZT0iMTJweCIgdGV4dC1hbmNob3I9Im1pZGRsZSI+QWJzdHJhY3Rpb248L3RleHQ+PC9zd2l0Y2g+PC9nPjxyZWN0IHg9IjI3MCIgeT0iMTYwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjQwIiByeD0iNiIgcnk9IjYiIGZpbGw9InJnYigyNTUsIDI1NSwgMjU1KSIgc3Ryb2tlPSJyZ2IoMCwgMCwgMCkiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMC41IC0wLjUpIj48c3dpdGNoPjxmb3JlaWduT2JqZWN0IHBvaW50ZXItZXZlbnRzPSJub25lIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiByZXF1aXJlZEZlYXR1cmVzPSJodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9mZWF0dXJlI0V4dGVuc2liaWxpdHkiIHN0eWxlPSJvdmVyZmxvdzogdmlzaWJsZTsgdGV4dC1hbGlnbjogbGVmdDsiPjxkaXYgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHN0eWxlPSJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogdW5zYWZlIGNlbnRlcjsganVzdGlmeS1jb250ZW50OiB1bnNhZmUgY2VudGVyOyB3aWR0aDogMTQ4cHg7IGhlaWdodDogMXB4OyBwYWRkaW5nLXRvcDogMTgwcHg7IG1hcmdpbi1sZWZ0OiAyNzFweDsiPjxkaXYgZGF0YS1kcmF3aW8tY29sb3JzPSJjb2xvcjogcmdiKDAsIDAsIDApOyAiIHN0eWxlPSJib3gtc2l6aW5nOiBib3JkZXItYm94OyBmb250LXNpemU6IDBweDsgdGV4dC1hbGlnbjogY2VudGVyOyI+PGRpdiBzdHlsZT0iZGlzcGxheTogaW5saW5lLWJsb2NrOyBmb250LXNpemU6IDEycHg7IGZvbnQtZmFtaWx5OiBIZWx2ZXRpY2E7IGNvbG9yOiByZ2IoMCwgMCwgMCk7IGxpbmUtaGVpZ2h0OiAxLjI7IHBvaW50ZXItZXZlbnRzOiBhbGw7IHdoaXRlLXNwYWNlOiBub3JtYWw7IG92ZXJmbG93LXdyYXA6IG5vcm1hbDsiPkltcGxlbWVudGF0aW9uPC9kaXY+PC9kaXY+PC9kaXY+PC9mb3JlaWduT2JqZWN0Pjx0ZXh0IHg9IjM0NSIgeT0iMTg0IiBmaWxsPSJyZ2IoMCwgMCwgMCkiIGZvbnQtZmFtaWx5PSJIZWx2ZXRpY2EiIGZvbnQtc2l6ZT0iMTJweCIgdGV4dC1hbmNob3I9Im1pZGRsZSI+SW1wbGVtZW50YXRpb248L3RleHQ+PC9zd2l0Y2g+PC9nPjxwYXRoIGQ9Ik0gMTUwIDE4MCBMIDI2My42MyAxODAiIGZpbGw9Im5vbmUiIHN0cm9rZT0icmdiKDAsIDAsIDApIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHBvaW50ZXItZXZlbnRzPSJzdHJva2UiLz48cGF0aCBkPSJNIDI2OC44OCAxODAgTCAyNjEuODggMTgzLjUgTCAyNjMuNjMgMTgwIEwgMjYxLjg4IDE3Ni41IFoiIGZpbGw9InJnYigwLCAwLCAwKSIgc3Ryb2tlPSJyZ2IoMCwgMCwgMCkiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjxlbGxpcHNlIGN4PSI3NSIgY3k9IjcuNSIgcng9IjcuNSIgcnk9IjcuNSIgZmlsbD0icmdiKDI1NSwgMjU1LCAyNTUpIiBzdHJva2U9InJnYigwLCAwLCAwKSIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjxwYXRoIGQ9Ik0gNzUgMTUgTCA3NSA0MCBNIDc1IDIwIEwgNjAgMjAgTSA3NSAyMCBMIDkwIDIwIE0gNzUgNDAgTCA2MCA2MCBNIDc1IDQwIEwgOTAgNjAiIGZpbGw9Im5vbmUiIHN0cm9rZT0icmdiKDAsIDAsIDApIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMC41IC0wLjUpIj48c3dpdGNoPjxmb3JlaWduT2JqZWN0IHBvaW50ZXItZXZlbnRzPSJub25lIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiByZXF1aXJlZEZlYXR1cmVzPSJodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9mZWF0dXJlI0V4dGVuc2liaWxpdHkiIHN0eWxlPSJvdmVyZmxvdzogdmlzaWJsZTsgdGV4dC1hbGlnbjogbGVmdDsiPjxkaXYgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHN0eWxlPSJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogdW5zYWZlIGZsZXgtc3RhcnQ7IGp1c3RpZnktY29udGVudDogdW5zYWZlIGNlbnRlcjsgd2lkdGg6IDFweDsgaGVpZ2h0OiAxcHg7IHBhZGRpbmctdG9wOiA2N3B4OyBtYXJnaW4tbGVmdDogNzVweDsiPjxkaXYgZGF0YS1kcmF3aW8tY29sb3JzPSJjb2xvcjogcmdiKDAsIDAsIDApOyAiIHN0eWxlPSJib3gtc2l6aW5nOiBib3JkZXItYm94OyBmb250LXNpemU6IDBweDsgdGV4dC1hbGlnbjogY2VudGVyOyI+PGRpdiBzdHlsZT0iZGlzcGxheTogaW5saW5lLWJsb2NrOyBmb250LXNpemU6IDEycHg7IGZvbnQtZmFtaWx5OiBIZWx2ZXRpY2E7IGNvbG9yOiByZ2IoMCwgMCwgMCk7IGxpbmUtaGVpZ2h0OiAxLjI7IHBvaW50ZXItZXZlbnRzOiBhbGw7IHdoaXRlLXNwYWNlOiBub3dyYXA7Ij5EZXY8L2Rpdj48L2Rpdj48L2Rpdj48L2ZvcmVpZ25PYmplY3Q+PHRleHQgeD0iNzUiIHk9Ijc5IiBmaWxsPSJyZ2IoMCwgMCwgMCkiIGZvbnQtZmFtaWx5PSJIZWx2ZXRpY2EiIGZvbnQtc2l6ZT0iMTJweCIgdGV4dC1hbmNob3I9Im1pZGRsZSI+RGV2PC90ZXh0Pjwvc3dpdGNoPjwvZz48cGF0aCBkPSJNIDc1IDE2MCBMIDc1IDk2LjM3IiBmaWxsPSJub25lIiBzdHJva2U9InJnYigwLCAwLCAwKSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBwb2ludGVyLWV2ZW50cz0ic3Ryb2tlIi8+PHBhdGggZD0iTSA3NSA5MS4xMiBMIDc4LjUgOTguMTIgTCA3NSA5Ni4zNyBMIDcxLjUgOTguMTIgWiIgZmlsbD0icmdiKDAsIDAsIDApIiBzdHJva2U9InJnYigwLCAwLCAwKSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PHJlY3QgeD0iMTcwIiB5PSIxNTAiIHdpZHRoPSI2MCIgaGVpZ2h0PSIzMCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJub25lIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTAuNSAtMC41KSI+PHN3aXRjaD48Zm9yZWlnbk9iamVjdCBwb2ludGVyLWV2ZW50cz0ibm9uZSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgcmVxdWlyZWRGZWF0dXJlcz0iaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHMTEvZmVhdHVyZSNFeHRlbnNpYmlsaXR5IiBzdHlsZT0ib3ZlcmZsb3c6IHZpc2libGU7IHRleHQtYWxpZ246IGxlZnQ7Ij48ZGl2IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiBzdHlsZT0iZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IHVuc2FmZSBjZW50ZXI7IGp1c3RpZnktY29udGVudDogdW5zYWZlIGNlbnRlcjsgd2lkdGg6IDU4cHg7IGhlaWdodDogMXB4OyBwYWRkaW5nLXRvcDogMTY1cHg7IG1hcmdpbi1sZWZ0OiAxNzFweDsiPjxkaXYgZGF0YS1kcmF3aW8tY29sb3JzPSJjb2xvcjogcmdiKDAsIDAsIDApOyAiIHN0eWxlPSJib3gtc2l6aW5nOiBib3JkZXItYm94OyBmb250LXNpemU6IDBweDsgdGV4dC1hbGlnbjogY2VudGVyOyI+PGRpdiBzdHlsZT0iZGlzcGxheTogaW5saW5lLWJsb2NrOyBmb250LXNpemU6IDEycHg7IGZvbnQtZmFtaWx5OiBIZWx2ZXRpY2E7IGNvbG9yOiByZ2IoMCwgMCwgMCk7IGxpbmUtaGVpZ2h0OiAxLjI7IHBvaW50ZXItZXZlbnRzOiBhbGw7IHdoaXRlLXNwYWNlOiBub3JtYWw7IG92ZXJmbG93LXdyYXA6IG5vcm1hbDsiPkvhur8gdGjhu6thPC9kaXY+PC9kaXY+PC9kaXY+PC9mb3JlaWduT2JqZWN0Pjx0ZXh0IHg9IjIwMCIgeT0iMTY5IiBmaWxsPSJyZ2IoMCwgMCwgMCkiIGZvbnQtZmFtaWx5PSJIZWx2ZXRpY2EiIGZvbnQtc2l6ZT0iMTJweCIgdGV4dC1hbmNob3I9Im1pZGRsZSI+S+G6vyB0aOG7q2E8L3RleHQ+PC9zd2l0Y2g+PC9nPjxyZWN0IHg9IjE3MCIgeT0iMTkwIiB3aWR0aD0iNjAiIGhlaWdodD0iMzAiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0wLjUgLTAuNSkiPjxzd2l0Y2g+PGZvcmVpZ25PYmplY3QgcG9pbnRlci1ldmVudHM9Im5vbmUiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHJlcXVpcmVkRmVhdHVyZXM9Imh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ZlYXR1cmUjRXh0ZW5zaWJpbGl0eSIgc3R5bGU9Im92ZXJmbG93OiB2aXNpYmxlOyB0ZXh0LWFsaWduOiBsZWZ0OyI+PGRpdiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgc3R5bGU9ImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiB1bnNhZmUgY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IHVuc2FmZSBjZW50ZXI7IHdpZHRoOiA1OHB4OyBoZWlnaHQ6IDFweDsgcGFkZGluZy10b3A6IDIwNXB4OyBtYXJnaW4tbGVmdDogMTcxcHg7Ij48ZGl2IGRhdGEtZHJhd2lvLWNvbG9ycz0iY29sb3I6IHJnYigwLCAwLCAwKTsgIiBzdHlsZT0iYm94LXNpemluZzogYm9yZGVyLWJveDsgZm9udC1zaXplOiAwcHg7IHRleHQtYWxpZ246IGNlbnRlcjsiPjxkaXYgc3R5bGU9ImRpc3BsYXk6IGlubGluZS1ibG9jazsgZm9udC1zaXplOiAxMnB4OyBmb250LWZhbWlseTogSGVsdmV0aWNhOyBjb2xvcjogcmdiKDAsIDAsIDApOyBsaW5lLWhlaWdodDogMS4yOyBwb2ludGVyLWV2ZW50czogYWxsOyB3aGl0ZS1zcGFjZTogbm9ybWFsOyBvdmVyZmxvdy13cmFwOiBub3JtYWw7Ij5UaOG7sWMgdGhpPC9kaXY+PC9kaXY+PC9kaXY+PC9mb3JlaWduT2JqZWN0Pjx0ZXh0IHg9IjIwMCIgeT0iMjA5IiBmaWxsPSJyZ2IoMCwgMCwgMCkiIGZvbnQtZmFtaWx5PSJIZWx2ZXRpY2EiIGZvbnQtc2l6ZT0iMTJweCIgdGV4dC1hbmNob3I9Im1pZGRsZSI+VGjhu7FjIHRoaTwvdGV4dD48L3N3aXRjaD48L2c+PHJlY3QgeD0iODAiIHk9IjExMCIgd2lkdGg9IjYwIiBoZWlnaHQ9IjMwIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMC41IC0wLjUpIj48c3dpdGNoPjxmb3JlaWduT2JqZWN0IHBvaW50ZXItZXZlbnRzPSJub25lIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiByZXF1aXJlZEZlYXR1cmVzPSJodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9mZWF0dXJlI0V4dGVuc2liaWxpdHkiIHN0eWxlPSJvdmVyZmxvdzogdmlzaWJsZTsgdGV4dC1hbGlnbjogbGVmdDsiPjxkaXYgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHN0eWxlPSJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogdW5zYWZlIGNlbnRlcjsganVzdGlmeS1jb250ZW50OiB1bnNhZmUgY2VudGVyOyB3aWR0aDogNThweDsgaGVpZ2h0OiAxcHg7IHBhZGRpbmctdG9wOiAxMjVweDsgbWFyZ2luLWxlZnQ6IDgxcHg7Ij48ZGl2IGRhdGEtZHJhd2lvLWNvbG9ycz0iY29sb3I6IHJnYigwLCAwLCAwKTsgIiBzdHlsZT0iYm94LXNpemluZzogYm9yZGVyLWJveDsgZm9udC1zaXplOiAwcHg7IHRleHQtYWxpZ246IGNlbnRlcjsiPjxkaXYgc3R5bGU9ImRpc3BsYXk6IGlubGluZS1ibG9jazsgZm9udC1zaXplOiAxMnB4OyBmb250LWZhbWlseTogSGVsdmV0aWNhOyBjb2xvcjogcmdiKDAsIDAsIDApOyBsaW5lLWhlaWdodDogMS4yOyBwb2ludGVyLWV2ZW50czogYWxsOyB3aGl0ZS1zcGFjZTogbm9ybWFsOyBvdmVyZmxvdy13cmFwOiBub3JtYWw7Ij5T4butIGThu6VuZzwvZGl2PjwvZGl2PjwvZGl2PjwvZm9yZWlnbk9iamVjdD48dGV4dCB4PSIxMTAiIHk9IjEyOSIgZmlsbD0icmdiKDAsIDAsIDApIiBmb250LWZhbWlseT0iSGVsdmV0aWNhIiBmb250LXNpemU9IjEycHgiIHRleHQtYW5jaG9yPSJtaWRkbGUiPlPhu60gZOG7pW5nPC90ZXh0Pjwvc3dpdGNoPjwvZz48L2c+PHN3aXRjaD48ZyByZXF1aXJlZEZlYXR1cmVzPSJodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9mZWF0dXJlI0V4dGVuc2liaWxpdHkiLz48YSB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLC01KSIgeGxpbms6aHJlZj0iaHR0cHM6Ly93d3cuZGlhZ3JhbXMubmV0L2RvYy9mYXEvc3ZnLWV4cG9ydC10ZXh0LXByb2JsZW1zIiB0YXJnZXQ9Il9ibGFuayI+PHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxMHB4IiB4PSI1MCUiIHk9IjEwMCUiPlRleHQgaXMgbm90IFNWRyAtIGNhbm5vdCBkaXNwbGF5PC90ZXh0PjwvYT48L3N3aXRjaD48L3N2Zz4=
```
- Một đoạn code quen thuộc
```csharp=
services.AddScoped<IBugFreeInterface, TwoHundredsImplementation>();
// thời gian fix bug như chó chạy, ta có thể có implementation mới vẫn đảm bảo tuân thủ interface
services.AddScoped<IBugFreeInterface, OneHundredImplementation>();
```
