นี่เป็นเรื่องง่ายที่จะทำเมื่อคุณเข้าใจว่า DI เกี่ยวกับรูปแบบและหลักการไม่ใช่เทคโนโลยี
ในการออกแบบ API ในวิธี DI Container-Agnostic ให้ปฏิบัติตามหลักการทั่วไปเหล่านี้:
โปรแกรมไปยังส่วนต่อประสานไม่ใช่การใช้งาน
หลักการนี้เป็นคำพูด (จากหน่วยความจำแม้ว่า) จากรูปแบบการออกแบบแต่ควรเป็นเป้าหมายที่แท้จริงของคุณเสมอ DI เป็นเพียงหมายถึงการบรรลุสิ้นสุดที่
ใช้หลักการฮอลลีวูด
ฮอลลีวู้ดหลักการในแง่ DI says: อย่าเรียก DI คอนเทนเนอร์ก็จะโทรหาคุณ
อย่าขอการพึ่งพาโดยตรงจากการเรียกคอนเทนเนอร์จากภายในโค้ดของคุณ ขอมันโดยปริยายโดยใช้สร้างฉีด
ใช้ตัวสร้างการฉีด
เมื่อคุณต้องการการพึ่งพาขอแบบคงที่ผ่านตัวสร้าง:
public class Service : IService
{
private readonly ISomeDependency dep;
public Service(ISomeDependency dep)
{
if (dep == null)
{
throw new ArgumentNullException("dep");
}
this.dep = dep;
}
public ISomeDependency Dependency
{
get { return this.dep; }
}
}
สังเกตว่าคลาส Service รับประกันค่าคงที่อย่างไร เมื่อมีการสร้างอินสแตนซ์การอ้างอิงนั้นจะสามารถใช้ได้เนื่องจากการรวมกันของ Guard Clause และreadonly
คำสำคัญ
ใช้ Abstract Factory หากคุณต้องการวัตถุที่มีอายุสั้น
การพึ่งพาการฉีดด้วย Constructor Injection มักจะมีอายุการใช้งานที่ยาวนาน แต่บางครั้งคุณจำเป็นต้องมีวัตถุระยะสั้นหรือสร้างการพึ่งพาโดยอ้างอิงจากค่าที่รู้จักในเวลาทำงานเท่านั้น
ดูสิ่งนี้สำหรับข้อมูลเพิ่มเติม
เขียนเฉพาะช่วงเวลาที่รับผิดชอบครั้งสุดท้ายเท่านั้น
ทำให้วัตถุแยกออกจนกว่าจะถึงจุดจบ โดยปกติคุณสามารถรอและเชื่อมต่อทุกอย่างในจุดเข้าใช้งานของแอปพลิเคชัน นี้เรียกว่ารากองค์ประกอบ
รายละเอียดเพิ่มเติมที่นี่:
ลดความซับซ้อนของการใช้ Facade
หากคุณรู้สึกว่า API ที่เกิดขึ้นนั้นซับซ้อนเกินไปสำหรับผู้ใช้มือใหม่คุณสามารถจัดเตรียมคลาสFacadeสองสามตัวที่รวมการรวมการพึ่งพาทั่วไปเข้าไว้ด้วยกัน
เพื่อให้ซุ้มที่มีความยืดหยุ่นพร้อมการค้นพบระดับสูงคุณสามารถพิจารณาจัดหาผู้สร้างที่คล่องแคล่ว บางสิ่งเช่นนี้
public class MyFacade
{
private IMyDependency dep;
public MyFacade()
{
this.dep = new DefaultDependency();
}
public MyFacade WithDependency(IMyDependency dependency)
{
this.dep = dependency;
return this;
}
public Foo CreateFoo()
{
return new Foo(this.dep);
}
}
สิ่งนี้จะทำให้ผู้ใช้สามารถสร้าง Foo เริ่มต้นโดยการเขียน
var foo = new MyFacade().CreateFoo();
อย่างไรก็ตามจะสามารถค้นพบได้มากว่าเป็นไปได้ที่จะให้การพึ่งพาที่กำหนดเองและคุณสามารถเขียน
var foo = new MyFacade().WithDependency(new CustomDependency()).CreateFoo();
หากคุณคิดว่าคลาส MyFacade นั้นมีการพึ่งพาที่แตกต่างกันมากมายฉันหวังว่ามันชัดเจนว่ามันจะให้ค่าเริ่มต้นที่เหมาะสมในขณะที่ยังคงสามารถค้นพบการขยายได้
FWIW นานหลังจากที่เขียนคำตอบนี้ผมขยายความแนวคิดนี้และเขียนบล็อกโพสต์ไม่เกี่ยวกับห้องสมุด DI-Friendlyและการโพสต์เกี่ยวกับสหายDI-Friendly กรอบ