มีวิธีการโอเวอร์โหลดที่ใช้คอนเทนเนอร์ IoC

ฉันกำลังเขียน API ไว้ด้านบนของวัตถุ COM และคุณต้องส่งผ่านวัตถุ COM ไปเป็นทุกประเภทและวิธีการคงที่ที่ฉันเขียน เพื่อที่ฉันจะได้ทดสอบแต่ละส่วนของ API ของฉันได้

ตอนนี้คำถามของฉันคือฉันมีวิธีการโอเวอร์โหลดสำหรับวิธีที่ใช้วัตถุ COM แต่ส่งผ่าน IoC ที่ได้รับการแก้ไขแล้วไปยังอีกวิธีหนึ่งแทน เพื่อให้ผู้ใช้ API ไม่ต้องกังวลกับการส่งผ่านในวัตถุ COM หรือฉันควรลบวิธีการโอเวอร์โหลดออกและแก้ไขโดยไม่มีตัวเลือกในการส่งต่อ

อธิบายยากนิดหน่อย นี่คือตัวอย่าง

ตัวอย่างคอนสตรัคเตอร์

FooType(IComObject obj,string table) {}
FooType(string table) : this(Ioc.Resolve<IComObject>(), table) {}

หรือเพียงแค่

FooType(string table) : this(Ioc.Resolve<IComObject>(), table) {}

ตัวอย่างวิธีการคงที่

public static SomeType Create(IComObject obj,string table) 
{ // Do some work with obj}

public static SomeType Create(string table) 
{ 
   return MyClass.Create(Ioc.Resolve<IComObject>(),table);
}

หรือเพียงแค่

public static SomeType Create(string table) 
{ 
   IComObject obj = Ioc.Resolve<IComObject>();
   return MyClass.Create(Ioc.Resolve<IComObject>(),table);
}

ความกังวลที่ใหญ่ที่สุดของฉันเกี่ยวกับการโอเวอร์โหลดคือมันจะสร้างวิธีการมากมายที่เพียงแค่โทรไม่ออก ฉันมีตัวเลือกอื่นใดอีกที่นี่หรือนี่เป็นวิธีที่ถูกต้องในการแก้ไขปัญหานี้

ป.ล. ฉันไม่ต้องการสร้างภาระให้ผู้ใช้ต้องส่งอินสแตนซ์ของ IComObject ไปทั่วแอปพลิเคชันของพวกเขา


person Nathan W    schedule 04.06.2009    source แหล่งที่มา
comment
ดูเหมือนว่าคำถามต่อเนื่องใน: stackoverflow.com/questions/947378/ถึงฉัน?   -  person jerryjvl    schedule 04.06.2009
comment
ใช่ มันค่อนข้างจะกังวลเรื่องรอยเปื้อนและการค้นพบได้ในอันนี้มากกว่า   -  person Nathan W    schedule 04.06.2009
comment
และถ้ามันถูกต้องที่จะทำสิ่งที่ฉันทำอยู่   -  person Nathan W    schedule 04.06.2009
comment
ไม่สามารถบอกคุณได้ต้องเจาะลึก IoC เพิ่มเติมก่อนจึงจะสามารถให้คำตอบที่ดีได้;)   -  person jerryjvl    schedule 04.06.2009


คำตอบ (4)


หลักการประการหนึ่งของ Dependency Injection คือ การขึ้นต่อกันของคลาสควรได้รับการเปิดเผยต่อโลกภายนอกอย่างชัดเจน เมื่อคลาสแก้ไขการพึ่งพาตัวเอง (ดังตัวอย่างที่สองของคุณ) มันจะขัดกับหลักการนั้นและมุ่งหน้ากลับไปสู่เส้นทางของการใช้บริการซิงเกิลตัน - แม้ว่าจะเป็นที่ยอมรับว่าคุณค่อนข้างดีกว่าเพราะคุณมีคอนเทนเนอร์ IoC เป็น "การหลบหนี ฟัก" เพื่อเยาะเย้ยวัตถุบริการ

แน่นอนว่าการมีโหลดพารามิเตอร์ทั้งหมดในตัวสร้างของอ็อบเจ็กต์ทั้งหมดของคุณนั้นค่อนข้างเป็นภาระ แต่นั่นคือจุดที่ IoC Container เข้ามา ถ้ามันรองรับการเดินสายอัตโนมัติและคุณใช้งานตามที่ได้รับการออกแบบ คุณมักจะพบว่าตัวเองมี เพื่อแก้ไขอินสแตนซ์เพียงไม่กี่รายการด้วยตัวคุณเอง: คุณดึงออบเจ็กต์แรกออกมา และออบเจ็กต์นั้นมาพร้อมกับการกำหนดค่าที่พร้อมสำหรับการขึ้นต่อกันทั้งหมด และออบเจ็กต์เหล่านั้นก็พร้อมสำหรับการกำหนดค่าพร้อมการขึ้นต่อกันทั้งหมดแล้ว และอื่นๆ ด้วยเหตุนี้ Joshua Flanagan สร้างอาร์กิวเมนต์ว่า IoC Containers จริงๆ ควรจะเรียกว่า IoC Composers

หากคุณต้องการหลีกเลี่ยงการสร้างภาระให้กับผู้ใช้ API ของคุณ ลองมีออบเจ็กต์โฟกัสที่ล้อมรอบคอนเทนเนอร์ IoC ของคุณและดึงอินสแตนซ์ที่กำหนดค่าไว้ออกมาเพื่อใช้โดยการเรียกโค้ดได้อย่างไร

person Samuel Jack    schedule 09.06.2009

จากมุมมองของฉัน เว้นแต่คุณจะมีเหตุผลที่น่าสนใจในการปล่อยให้โอเวอร์โหลด การมีทั้ง (โอเวอร์โหลดและการแก้ไข) จะทำให้ API ของคุณซับซ้อนโดยไม่จำเป็นและนำไปสู่ปัญหาที่อาจเกิดขึ้นกับผู้ใช้ของคุณมากเกินไป

ฉันคิดว่าคุณได้ตอบคำถามของคุณเองแล้วเมื่อคุณพูดว่า "ป.ล. ฉันไม่อยากสร้างภาระให้กับผู้ใช้จริงๆ"

person Matthew Pelser    schedule 07.06.2009

จากด้านหนึ่งคุณสามารถวางวิธีการเช่น

public static SomeType Create(IComObject obj,string table) 

เลยเพราะคุณสามารถลงทะเบียนวัตถุจำลองประเภท IComObject ในระหว่างการทดสอบและรันการทดสอบเหล่านี้ได้อย่างง่ายดาย
แต่ในอีกด้านหนึ่ง สิ่งนี้จะทำให้หลักการ SoC และ Open/Closed เสียหาย วิธีการของคุณรู้มากเกินไปในกรณีนี้ (ว่ามี DI บ้างเป็นต้น) จากด้านการออกแบบ (สถาปัตยกรรม) จะดีกว่าถ้าใช้วิธีการเช่น "สร้าง (IComObject obj, ตารางสตริง)" เท่านั้น และปรับโครงสร้างโค้ดใหม่เพื่อลดการใช้ Ioc.Resolve() และใช้เฉพาะในเครื่องมือเริ่มต้น แฟบริค หรืออะไรทำนองนี้เท่านั้น และเป็นการยากมากที่จะอธิบายวิธีการปรับโครงสร้างใหม่โดยไม่เห็นโค้ดทั้งหมด
ดังนั้นคำตอบก็คือ - มันขึ้นอยู่กับ
แก้ไข:
มี โพสต์ที่ดีมากเกี่ยวกับ กรณีนี้. ตรวจสอบมันมีคำตอบ =)

person zihotki    schedule 08.06.2009

หากผู้ใช้สนใจอินสแตนซ์ IComObject การสร้างโอเวอร์โหลดก็เป็นวิธีที่จะไป

หาก IComObject เป็นรายละเอียดการใช้งานสำหรับผู้ใช้ของคุณ และคุณเป็นคนเดียวที่สนใจเกี่ยวกับการทดสอบ คุณควรเปิดเผยวิธีการแบบ Factory ง่ายๆ ที่คลาสของคุณใช้เพื่อสร้างอินสแตนซ์/เข้าถึง IComObject ภายใน

โดยทั่วไป หากผู้ใช้ให้ความสำคัญกับ IComObject มันก็จะไม่เป็นภาระหากคุณสร้างการโอเวอร์โหลด โดยส่วนตัวแล้วในฐานะนักพัฒนาซอฟต์แวร์ ฉันเสมอต้องการตัวเลือกให้มากที่สุดเท่าที่จะทำได้

person John Weldon    schedule 12.06.2009