การฉีดพึ่งพาอาศัยกันสามารถรวมเข้ากับภาษาได้อย่างไร? [ปิด]


10

ฉันได้คิดเล็กน้อยเกี่ยวกับวิธีการฉีดพึ่งพาสามารถบูรณาการโดยตรงในภาษา C # เช่น ฉันคิดวิธีแก้ปัญหาที่เป็นไปได้ฉันอยากฟังความคิดเห็นของคุณ ฉันไม่ได้ใช้กรอบการฉีดพึ่งพาหลายคนดังนั้นอาจมีบางสิ่งที่ฉันมองเห็น

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

ในทำนองเดียวกันคุณลงทะเบียนเครื่องจัดการสำหรับประเภทที่แตกต่างกับบริการนั้นเพื่อให้คุณสามารถยกตัวอย่างประเภททรัพย์สินที่ฉีด

ข้อดีของการใช้สถาปัตยกรรม IMO ประเภทนี้คือความยืดหยุ่นและใช้งานง่าย ข้อเสียคืออาจมีค่าใช้จ่ายในการทำไฮไลต์บางครั้งในแต่ละครั้งที่คุณเริ่มชั้นเรียนที่มีการฉีด

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

ความคิดปัญหาคำถามความคิดที่ดีกว่า

รหัส

public class SomeClass
{

  public SomeClass()
  {
     //implicit behavior if Animal is not set in constructor or initializer
    this.Animal =  GlobalInjector.Get(this,typeof(Mammal))

  }

  public injectable Mammal Animal  
  {
   get;
   set;
  }
}


 GlobalInjector.Register(typeof(Mammal), () => return new Mammal(someParameter));

คุณช่วยยกตัวอย่างรหัสหลอกสำหรับพวกเราที่ไม่คุ้นเคยกับ DI ได้ไหม? PS บางทีคุณสามารถตอบคำถามของฉันเกี่ยวกับ DI ได้หรือไม่ :)
Steven

2
ฉันไม่แน่ใจว่าฉันจะได้รับมัน คุณสามารถรับทุกสิ่งที่มี DI คอนเทนเนอร์ทั่วโลกและแอตทริบิวต์ '[Injectable]' แทนที่จะเป็นคำหลักใช่ไหม
nikie

สวัสดีฉันพยายามเขียนเล็กน้อยเกี่ยวกับ DI ในคำถามของคุณไม่แน่ใจว่ามันจะตอบได้ไหม
Homde

nikie: ใช่ฉันเดาว่าคุณสามารถใช้กลไกจริงในรูปแบบที่แตกต่างกันฉันสนใจมากขึ้นถ้าลอจิกพื้นฐานเป็นเสียง
Homde

ดังนั้นสิ่งที่แตกต่างระหว่างสิ่งนี้กับ IoC ที่มีอยู่นอกเหนือจากคำหลักพิเศษของคุณ?
Matthew Whited

คำตอบ:


7

มีหลายสิ่งที่เป็นภาษาและสิ่งที่ไม่เป็น นานมาแล้ว C ได้รับการยอมรับว่า IO ไม่ได้อยู่ในภาษาเพราะมันเป็นรูปแบบการคำนวณภายนอกและสามารถนำไปใช้กับฟังก์ชั่นไลบรารี

การพึ่งพาการฉีดเป็นเช่นนั้น เป็นภาษาภายนอกและสามารถนำไปใช้กับกรอบงานที่เหมาะสม

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


ฉันเห็นด้วยในทางทฤษฎีคุณไม่สามารถมีภาษาที่ทุกฟังก์ชั่นเป็นคุณสมบัติของภาษาโดยไม่ต้องมีการบวม อย่างไรก็ตามมีพื้นที่สำหรับนามธรรมที่สูงขึ้นใหม่ที่ช่วยให้เราเขียนโค้ดได้ดีขึ้น บางทีการฉีดพึ่งพาต่อกันไม่ใช่ปัญหาที่ต้องแก้ไข แต่ปัญหาที่อยู่นั่นคือวิธีที่จะทำให้ง่ายขึ้นสำหรับเราในการลดการพึ่งพา นี้ไม่อาจจะเป็นวิธีที่ดีที่สุดที่จะทำมันแม้ว่า :)
Homde

5

มันไม่จำเป็น

หนึ่งในสิ่งที่ฉันชอบที่สุดเกี่ยวกับ DI Framework ที่ดีที่สุดที่ฉันเคยใช้คือรหัสการกำหนดค่าระดับบนสุดเป็นเพียงส่วนหนึ่งของรหัสของคุณที่จำเป็นต้องรู้เกี่ยวกับ DI การเดินสายอัตโนมัติเสร็จแล้วที่คอนเทนเนอร์และการกำหนดค่า / ระดับ "การโหลดโมดูล" และรหัสแอปพลิเคชันของคุณสามารถลบล้างได้อย่างสมบูรณ์

ซึ่งหมายความว่าไม่มีแอตทริบิวต์ไม่มีสายวิเศษไม่มีการประชุม โค้ดแต่ละชิ้นรู้เพียงว่ามันยอมรับโค้ดใน Constructor (/ properties / methods) และนั่นคือทั้งหมด

ด้วยการออกแบบที่คุณไม่จำเป็นต้องเปลี่ยนภาษาเลยเพื่อรองรับ Dependency Injection

อาจเป็นอันตรายได้

สิ่งที่ฉันกลัวที่สุดเกี่ยวกับระบบฉีดพึ่งพาภาษาแบบบูรณาการคือมันจะเพิ่มอุปสรรคในการดำเนินการอื่น ๆ แต่มันอาจจะวาดตัวเองลงในมุมในบางแง่มุม

วิธีบางอย่างที่มันสามารถทาสีตัวเองลงในมุม:

  • รองรับเฉพาะการกำหนดค่าที่ยึดตาม XML หรือการกำหนดค่าที่ใช้รหัสเท่านั้น
  • ไม่สามารถสนับสนุนรูปแบบการออกแบบจากโรงงานได้อย่างหมดจด (ไม่เพียง แต่ส่วนประกอบชั่วคราว: ส่วนประกอบที่สร้างขึ้นขณะใช้งาน)
  • อย่างใดการเปลี่ยนรหัสของฉันดังนั้นฉันถูกบังคับให้ใช้การฉีดพึ่งพาและไม่เพียงแค่ยกตัวอย่างชั้นเรียนของฉันสำหรับการทดสอบหน่วย
  • ไม่รองรับวงจรชีวิตที่กำหนดเอง
  • ไม่สามารถขยายได้
  • ไม่สามารถเปลี่ยนได้ในกรณีที่ฉันต้องการการปรับแต่งที่มากขึ้น
  • การถูกทำลายอย่างใดที่เรายังไม่เข้าใจเพราะเราผู้ใช้. NET ยังไม่ได้ใช้ DI นานพอที่จะรู้ถึงข้อผิดพลาด

4

คุณเห็นManaged Extensibility Frameworkที่มาพร้อมกับ. NET 4 หรือไม่ นี่คือบทความที่ฉันเขียนด้วยตัวอย่าง โดยทั่วไปมันเป็นรูปแบบของการฉีดพึ่งพาสร้างขึ้นใน. NET ด้วยคุณสมบัติเพิ่มเติมของการค้นพบเวลาทำงาน

การฉีดคุณสมบัติมีลักษณะเช่นนี้:

class Program
{
    [Import]
    public IMessageSender MessageSender { get; set; }
}

Constructor injections มีลักษณะดังนี้:

class Program
{
    [ImportingConstructor]
    public Program(IMessageSender messageSender) 
    {
    ...
    }
}

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


ในขณะที่ MEF เป็นจริงเย็นสำหรับสิ่งปลั๊กอินฉันไม่คิดว่าฉันต้องการที่จะใช้มันเป็นกลไก DI ทั่วไป
Homde

1
@MKO - คุณช่วยอธิบายสิ่งที่ขาดไปได้ไหม? ฉันรู้ถึงบทความทั้งหมดที่ Glenn Block แข่งเพื่อสร้างความมั่นใจให้กับคนที่ MEF ไม่ได้ออกมาแทนที่กรอบ DI ทั้งหมด แต่ถ้าคุณดูรายละเอียดมันชัดเจนว่ามันเป็นแถลงการณ์ทางการเมืองมากกว่าสิ่งอื่นใด อย่างไรก็ตามหากคุณสามารถให้รายการคุณลักษณะที่ดีที่ MEF ขาดเมื่อเทียบกับกรอบ DI อื่น ๆ ที่จะช่วยให้ผู้คนตัดสินใจอย่างชาญฉลาด นอกจากนี้คำถามเกี่ยวกับ DI Framework ใน C # และ MEF เป็น DI container อย่างชัดเจนใน. NET Framework
Scott Whitlock

2
  1. คุณไม่ได้อธิบายกลไกการกำหนดค่าซึ่ง IMHO เป็นบิตที่ยุ่งยาก คุณจะทำให้รหัสทั้งหมดทำงานในหนึ่งเธรดได้อย่างไรใช้การเชื่อมต่อฐานข้อมูล A และรหัสทั้งหมดในการเชื่อมต่อเธรดอื่น B คุณจะบล็อกการฉีดทรัพยากรบางอย่างได้อย่างไรเนื่องจากผู้ใช้ที่เข้าสู่ระบบในปัจจุบันไม่ได้รับอนุญาตให้เข้าถึง?
  2. อย่าใช้หัวฉีดทั่วโลก อย่าใช้สิ่งที่เป็นสากลเลยหรือคุณอาจใช้ตัวแปรทั่วโลกเช่นกัน ไม่การใช้ OOP- พูดเช่นซิงเกิลตันหรือ "คงที่" แทนที่จะเป็นโกลบอลจะไม่เปลี่ยนธรรมชาติของโลก
  3. พิจารณาคอนเทนเนอร์ที่กำหนดขอบเขตแบบไดนามิก ในขณะที่การกำหนดขอบเขตคำศัพท์ได้รับชัยชนะอย่างถูกต้องเมื่อเทียบกับการกำหนดขอบเขตแบบไดนามิกฉันเชื่อว่าขอบเขตแบบไดนามิกจะทำการทดแทนที่ดีสำหรับขอบเขตระดับโลก การสืบทอดที่แตกต่างกันจะเป็นการใช้งานที่ดี (เช่นในการสืบทอดตามต้นแบบ)
  4. ฉันเชื่อว่ากลไก DI ที่ได้รับคำสั่งจากภาษาควรจะง่ายจริงๆไม่มีสิ่งที่กล้าได้กล้าเสียที่เป็นบรรทัดฐานใน C # และ Java กลไกการกำหนดขอบเขตแบบไดนามิกที่มีเลเยอร์การตั้งค่าที่เรียบง่ายอยู่ด้านบนอาจทำการหลอกลวงได้ โซลูชันของ Enterprisey สามารถถูกจัดเรียงอยู่ในอันดับต้น ๆ โดยบุคคลที่สาม
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.