IContextฉันมีอินเตอร์เฟซที่เรียกว่า สำหรับวัตถุประสงค์นี้ไม่สำคัญว่าจะทำอะไรยกเว้นดังต่อไปนี้:
T GetService<T>();
สิ่งที่วิธีนี้ทำคือดูที่ DI คอนเทนเนอร์ปัจจุบันของแอ็พพลิเคชันและพยายามแก้ไขการพึ่งพา ฉันคิดว่าค่อนข้างมาตรฐาน
ในแอปพลิเคชัน ASP.NET MVC ของฉันคอนสตรัคของฉันมีลักษณะเช่นนี้
protected MyControllerBase(IContext ctx)
{
TheContext = ctx;
SomeService = ctx.GetService<ISomeService>();
AnotherService = ctx.GetService<IAnotherService>();
}
ดังนั้นแทนที่จะเพิ่มหลายพารามิเตอร์ในตัวสร้างสำหรับแต่ละบริการ (เพราะจะทำให้รำคาญและใช้เวลานานสำหรับนักพัฒนาที่ขยายแอปพลิเคชัน) ฉันใช้วิธีนี้เพื่อรับบริการ
ตอนนี้ก็รู้สึกผิด แต่วิธีการที่ฉันกำลังเหตุผลมันอยู่ในหัวของฉันนี้ - ฉันจะเยาะเย้ยมัน
ฉันสามารถ. IContextการทดสอบตัวควบคุมนั้นคงไม่ยาก ฉันจะต้องต่อไป:
public class MyMockContext : IContext
{
public T GetService<T>()
{
if (typeof(T) == typeof(ISomeService))
{
// return another mock, or concrete etc etc
}
// etc etc
}
}
แต่อย่างที่ฉันพูดมันให้ความรู้สึกผิด ยินดีต้อนรับความคิด / การละเมิดใด ๆ
public SomeClass(Context c)มันเป็นเรื่องง่าย: รหัสนี้ค่อนข้างชัดเจนใช่ไหม มันฯ , ขึ้นอยู่กับthat SomeClass Contextเอ่อ แต่เดี๋ยวก่อนมันไม่ได้! มันขึ้นอยู่กับการพึ่งพาที่Xได้รับจากบริบทเท่านั้น นั่นหมายความว่าทุกครั้งที่คุณทำการเปลี่ยนแปลงContextมันสามารถทำลายSomeObjectแม้ว่าคุณจะเปลี่ยนแปลงเฉพาะsContext Yแต่ใช่คุณรู้ว่าคุณมีการเปลี่ยนแปลงเพียงYไม่ได้Xดังนั้นSomeClassเป็นเรื่องปกติ แต่การเขียนรหัสที่ดีนั้นไม่เกี่ยวกับสิ่งที่คุณรู้ แต่สิ่งที่พนักงานใหม่รู้เมื่อเขาดูรหัสของคุณเป็นครั้งแรก