
وقتی اولین بار اسم «Dependency Injection» رو شنیدم با خودم فکر کردم چه چیز پیچیدهایه. اما وقتی فرصتش رو پیدا کردم که ببینم مردم راجع به چی صحبت میکنن، با خودم گفتم همش همینه؟
ا Dependency Injection لفظ سنگینیه برای یه مفهوم ساده. یه اسم بد برای یه ابزار خوب. اما مقالات برتر گوگل از الفاظ و روش های پیچیدهای برای توضیح این مفهوم استفاده کردن. به نظرم اومد بهتره این موضوع رو به صورت سادهتر بیان کنم.
ا Dependency Injection به این معنیه که به یک آبجکت اینستنس متغیرهاش رو پاس بدیم. همین!
کلاسها چیزهایی دارن که بهشون میگیم متد. بیاید اسمشون رو بذاریم «Dependency». بیشتر مردم بهشون میگن متغیر.
public class Example { private DatabaseThingie myDatabase; public Example() { myDatabase = new DatabaseThingie(); } public void DoStuff() { ... myDatabase.GetData(); ... } }
اینجا ما یک متغیر، چیز، Dependency داریم به اسم myDatabase. که توی کانستراکتور مقداردهی اولیهش میکنیم.
اگر میخواستیم میتونستیم متغیر رو به کانستراکتور پاس بدیم. در این صورت dependency رو به کلاس inject میکردیم. حالا وقتی که از متغیر (dependency) استفاده میکنیم، داریم به جای اونی که ساختیم از اونی که بهمون داده شده استفاده میکنیم.
public class Example { private DatabaseThingie myDatabase; public Example() { myDatabase = new DatabaseThingie(); } public Example(DatabaseThingie useThisDatabaseInstead) { myDatabase = useThisDatabaseInstead; } public void DoStuff() { ... myDatabase.GetData(); ... } }
و این همهی چیزیه که وجود داره. بقیهی ماجرا تفاوتهای ساختاری و شکل و شمایله. شما میتونید dependency (متغیر) رو توی یک متد setter مقداردهی کنید. شما میتونید dependency رو با صدا زدن یک متد setter که توی یک اینترفیس به خصوص تعریف شده مقداردهی کنید. شما میتونید dependency رو یک اینترفیس کنید و بعد به صورت پلی مورفیسم مقادیر رو پاس بدید. هرچی.
علاوه بر چیزهای دیگه، این کار برای ایزوله کردن کلاسها زمان تست به درد می خوره.
public class ExampleTest { TestDoStuff() { MockDatabase mockDatabase = new MockDatabase(); // MockDatabase is a subclass of DatabaseThingie, so we can // "inject" it here: Example example = new Example(mockDatabase); example.DoStuff(); mockDatabase.AssertGetDataWasCalled(); } } public class Example { private DatabaseThingie myDatabase; public Example() { myDatabase = new DatabaseThingie(); } public Example(DatabaseThingie useThisDatabaseInstead) { myDatabase = useThisDatabaseInstead; } public void DoStuff() { ... myDatabase.GetData(); ... } }
همینه. Dependency injection در واقع پاس دادن یک اینستنس متغیره.
راههای زیادی هست که بشه این موضوع ساده رو پیچیده کرد. (راههای زیادی هست که بشه هر موضوعی رو پیچیده کرد! سادگی سخته.) بعضی زمانها همچین پیچیدگیای لازمه... و این هیچوقت اتخاب اول من نیست. من تصمیم گرفتم که این پیچیدگیها رو اینجا عنوان نکنم، اما اگه شما واقعا میخواید بدونید، این منابع رو چک کنید: