ฉันจะสรุปเครื่องมือ DI ของฉันจากเลเยอร์ UI/Service ได้อย่างไร

คำถามนี้เป็นคำถามต่อเนื่องจากนี้คำถามที่ฉันโพสต์เมื่อสุดสัปดาห์ที่ผ่านมา

ณ ตอนนี้ ฉันมีสิ่งนี้ในชั้นบริการของฉันซึ่งพูดคุยกับ UI ในแอปพลิเคชัน MVC

IDepartmentService deptService = kernel.Get<IDepartmentService>();
IList<Department> deptList = deptService.GetAllDepartments();

ทุกอย่างเรียบร้อยดีและ DI ก็ทำงานได้ตามที่คาดไว้ อย่างไรก็ตาม ด้วยเหตุผลบางอย่าง หากฉันตัดสินใจใช้ Structuremap เลเยอร์บริการทั้งหมดของฉันต้องมีการเปลี่ยนแปลง ฉันจะสรุปได้อย่างไรเพื่อให้การเปลี่ยนแปลงในเครื่องมือ DI จะไม่ส่งผลกระทบต่อชั้นบริการของฉันหรือมีผลกระทบน้อยที่สุด


person NoobDeveloper    schedule 01.08.2013    source แหล่งที่มา


คำตอบ (1)


อย่างไรก็ตาม ด้วยเหตุผลบางอย่าง หากฉันตัดสินใจใช้ Structuremap เลเยอร์บริการทั้งหมดของฉันต้องมีการเปลี่ยนแปลง

ที่ไม่เป็นความจริง. ดังที่แสดงในเธรดที่แล้ว Service Layer ไม่ทราบอะไรเกี่ยวกับกรอบงาน DI

คุณควรมีเลเยอร์ชื่อ composition root นี่เป็นเลเยอร์เดียวที่รับรู้ถึงกรอบงาน DI และเลเยอร์พื้นฐานทั้งหมด นี่คือที่ที่คุณกำลังจัดองค์ประกอบภาพ ดังนั้นหากคุณเปลี่ยนเฟรมเวิร์ก DI สถานที่เดียวที่คุณต้องทำการเปลี่ยนแปลงก็คือในรูทการเรียบเรียง

ดังนั้นคุณควรกำจัด kernel.Get<> สายออกจากบริการของคุณโดยเด็ดขาด ขณะนี้คุณกำลังใช้ Service Locator ไม่ใช่ การพึ่งพาการฉีด Service Locator เป็นรูปแบบต่อต้าน ชั้นบริการของคุณควรมีลักษณะดังนี้:

public class MyService
{
    private readonly ISomeDependency dependency;
    public MyService(ISomeDependency dependency)
    {
        this.dependency = dependency;
    }

    public void SomeMethod()
    {
        // do something with the dependency here
    }
}

แทน:

public class MyService
{
    private readonly ISomeDependency dependency;
    public MyService()
    {
        this.dependency = kernel.Get<ISomeDependency>();
    }

    public void SomeMethod()
    {
        // do something with the dependency here
    }
}
person Darin Dimitrov    schedule 01.08.2013
comment
บล็อกโค้ดแรกของคุณคือสิ่งที่ฉันมีในชั้นบริการของฉัน อย่างไรก็ตาม จะเกิดอะไรขึ้นหากฉันต้องการอินสแตนซ์ของ ISomeAnotherDependency ในวิธีเดียวจากหลายวิธีของคลาส MyService เพื่อดึงข้อมูล ฉันควรใส่มันไว้ในตัวสร้างหรือไม่ นั่นคือเหตุผลที่ฉันมีวิธี kernel.Get‹› ณ ​​ตอนนี้ เพื่อที่ฉันจะได้รับอินสแตนซ์ของ ISomeAnotherDependency ฉันต้องการกำจัดมันออกไป และด้วยเหตุนี้ฉันจึงคิดถึง ILocator.Get‹TypeName› ซึ่งจะทำให้ฉันมีอินสแตนซ์ของประเภทที่ต้องการ คุณคิดว่านี่เป็นแนวทางที่ไม่ดีหรือไม่? - person NoobDeveloper; 01.08.2013
comment
ใช่ ส่งผ่านเป็นการพึ่งพาคอนสตรัคเตอร์ การฉีด Constructor ใช้เพื่อส่งต่อการพึ่งพาไปยังคลาสโดยที่คลาสนี้ไม่สามารถทำงานได้อย่างถูกต้อง ในกรณีของคุณ แม้ว่าคุณจะมีเพียง 1 วิธีที่ต้องอาศัยการขึ้นต่อกันนี้ แต่ก็ยังต้องอาศัยการขึ้นต่อกันเพื่อให้บริการทำงานได้อย่างถูกต้อง และอย่าใช้รูปแบบ Service Locator นี่คือรูปแบบการต่อต้าน คุณควรทำงานกับกรอบงาน DI ในรูทการแต่งเพลงเท่านั้น - person Darin Dimitrov; 01.08.2013
comment
สมบูรณ์แบบ. ขอบคุณอีกครั้ง. ฉันได้ทำเครื่องหมายคำตอบของคุณเป็นคำตอบแล้ว อีกหนึ่งคำถามเท่านั้น ฉันจะทดสอบชั้นบริการของฉันได้อย่างไร ฉันควรขึ้นการพึ่งพาใหม่ด้วยตนเองโดยส่งผ่านตัวสร้างและทดสอบวิธีการของเลเยอร์บริการหรือไม่ - person NoobDeveloper; 01.08.2013
comment
หากคุณต้องการทดสอบเลเยอร์บริการของคุณแบบแยกส่วน คุณควรใช้เฟรมเวิร์กจำลองเพื่อส่งอินสแตนซ์จำลองของการขึ้นต่อกันในบริการของคุณสำหรับการทดสอบหน่วย ด้วยวิธีนี้ คุณจะสามารถควบคุมลักษณะการทำงานของการขึ้นต่อกันนี้ได้อย่างสมบูรณ์ และคุณมีความเป็นไปได้ในการทดสอบหน่วยโดยแยกการทำงานทั้งหมดที่มีอยู่ในชั้นบริการนี้ - person Darin Dimitrov; 02.08.2013
comment
ในตัวอย่างที่คุณให้มา MyService ขึ้นอยู่กับ ISomeDependency ดังนั้นฉันควรใช้ mocking framework (Moq) เพื่อจำลอง ISomeDependency หรือไม่ หรือฉันควรล้อเลียนเครื่องมือ DI? ฉันสับสนเล็กน้อยเกี่ยวกับเรื่องนี้ ณ ตอนนี้ฉันไม่ได้ใช้เฟรมเวิร์กการเยาะเย้ยใด ๆ แต่สร้าง MyService และ ISomeDependency ด้วยตนเองแทนเพื่อทดสอบวิธีจาก MyService ขอบคุณที่สละเวลา. - person NoobDeveloper; 02.08.2013
comment
ในการทดสอบหน่วยของคุณ คุณไม่ได้ใช้ DI ใด ๆ คุณสามารถใช้เฟรมเวิร์กการเยาะเย้ยได้หากคุณต้องการฉีด ISomeDependency ที่เยาะเย้ยลงในบริการ หรือหากคุณไม่ต้องการใช้เฟรมเวิร์กการเยาะเย้ย คุณสามารถเขียนการใช้งานอินเทอร์เฟซนี้เยาะเย้ยด้วยตัวคุณเองสำหรับการทดสอบหน่วยซึ่งโดยปกติแล้วจะทำงานหนักมาก และสาเหตุที่ผู้คนสร้างกรอบการเยาะเย้ยเช่น Moq - person Darin Dimitrov; 02.08.2013