ویرگول
ورودثبت نام
جواد جهانگیری
جواد جهانگیری
خواندن ۷ دقیقه·۳ سال پیش

آموزش تزریق وابستگی DependencyInjectionیا(DI) در C# asp.net core

به نام آن که جان را فکرت آموخت / چراغ دل به نور جان برافروخت

با عرض سلام و وقت بخیر خدمت کاربران محترم سایت ویرگول، در این مقاله آموزشی به موضوع DependencyInjectionیا(DI) در C# asp.net core پرداخته می شود و سعی شده یک آموزش کاربردی و پروژه محور از بحث تزریق وابستگی ها ارایه گردد.ایده این سری مقاله های آموزشی از این موضوع سرچشمه می گیرد که بخشی از خوانندگان وجود دارد که به محتوای نوشتاری آنلاین بهتر پاسخ می دهند و ترجیج می دهند مهارت های جدید را به سرعت از طریق خواندن افزایش دهند.این سری اموزش ها با ارایه پکیج آموزشی کاربردی در خصوص C# asp.net core آغاز می شود که انتظار می رود با واکنش مثبت کاربران همراه شود.

توجه: این مقاله به مرور زمان، ویرایش و یا تکمیل می‌شود!
تقاضا: در صورتی که با مشکل تایپی، دستوری و یا مفهومی در این مقاله برخورد کردید، از شما دوست عزیز و گرامی، صمیمانه تقاضا می‌کنم که اینجانب را مطلع کرده، تا نسبت به تصحیح و یا تکمیل آن، در اسرع وقت، اقدام نمایم.
با کمال تشکر جواد جهانگیری
شماره تلفن همراه: 09149431772
نشانی پست الکترونیکی: javad.jahangiri.niopdc@gmail.com
فیلم‌های آموزشی در آپارات:جواد جهانگیری (CTO) - آپارات
فیلم آموزشی در یوتویب: javad jahangiri - YouTube
نسخه مقاله: ۱.۱ - تاریخ بروزرسانی: 1400/09/09


شما فرض کنید کلاسی داریم که تسک خاصی را انجام می دهد و برای انجام این کار به کلاس های دیگری نیاز دارد و به تسک دیگری نیاز دارد در حقیقت نیاز به یک ابجکت از یک کلاس دیگر دارد در این حالت در جای که به ان نیاز داریم بجای اینکه از این ابجکت new کنیم در این حالت این ابجکت را Inject می کنیم یا بعبارتی انرا تزریق می کنیم یا بعبارت دیگر ان سرویس ها را برای ان تامین می کنیم که بتونه کار ما را انجام دهد

https://www.aparat.com/javadjahangiriniopdc/playlists


ما برای تزریق وابستگی ها سه حالت داریم :

  • از طریق تابع سازنده که بهترین روش می باشد
  • از طریق property
  • از طریق متد method

یک پروژه از نوع asp.net core web app (model-view-controller) ایجاد می کنیم :

یک نام دلخواه به پروژه می دهیم

تراگت فریم ورک بر روی .NET5.0 قرار می دهیم

در نهایت پروژه نمونه ای به شرح ذیل ساخته می شود:

دو پوشه بنام های IServices و Services به پروژه اضافه می کنیم

و در داخل پوشه IServices یک اینترفیس بنام ISampleService ایجاد می کنیم که دارای یک تابع بنام SampleFunction می باشد

سپس یک سرویس بنام SampleService را نیز به پوشه Services اضافه می کنیم که اینترفیس ISampleService را پیاده سازی می کند

در ادامه یک اینترفیس دیگر بنام IMyService در پوشه اینترفیس سرویس ها ایجاد می کنیم که دارای یک تابع بنام MyFunction می باشد که این تابع برای محاسبات خود به SampleFunction نیاز دارد

و در ادامه یک سرویس نیز بنام MyService ایجاد می کنیم که اینترفیس IMyService را پیاده سازی می کند

توجه داشته باشید که MyService برای انجام عملیات محاسبات خود به SampleService به شکل زیر نیاز دارد تقریبا منطق انجام کار به شرح ذیل خواهد بود:


حالا فرض کنید ما می خواهیم در کنترلر از این سرویس MyService به شرح ذیل استفاده کنیم:

هرکار انجام بدهیم با خطا مواجه خواهیم شد زیرا MyService برای اجرا نیاز به SampleService را دارد ما می توانیم چندتا کار انجام بدهیم

روش اول :property

به داخل MyService رفته و آبجکت SampleService را به public تغییر داده و در کنترلر آن را با ابجکت جدید مقدار دهی می کنیم و اگر کاربر فراموش کند که SampleService را با یک ابجکت جدید مقدار دهی کند برنامه دچار خطا می شود

روش دوم : با استفاده از متد (یک واسط )

در این روش یک متد می نویسیم که وظیفه ایجاد و تخصیص ابجکت را بر عهده بگیرد

و در داخل کنترلر ان را فراخوانی و یک ابجکت جدید SampleService را به ان پاس می کنیم و این روش نیز جالب نیست و اگر کار فراموش کند که متد را فراخوانی کند برنامه با خطا مواجه می شود


روش سوم :تابع سازنده که بهترین روش می باشد و اکثر IOC Container آن را پشتیبانی می کنند

در این روش یک تابع سازنده ساخته شده و ابجکت مورد نیاز از طریق سازنده به داخل کلاس تزریق می شود.


خوبی این روش این است که هنگام که برنامه نویس می خواهد از سرویس یک ابجکت ایجاد کند مجبورا باید نیازمندی های را نیز برای تابع سازنده ساخته و ارسال نمایید

اما در عمل و واقعیت ما نمی خواهیم خودمان این کار را انجام دهیم و در واقع می خواهیم یک نفر دیگر این کار را برای ما انجام دهد یعنی بعبارتی سرویس ما نیازمندهای خودش را به ان اعلام نمایید و ان چیز قبل از ایجاد ابجکت این نیازمندهای را برای ان ایجاد و به ان پاس نمایید که این کار IOC Container مثل ninject انجام می دهد که در دانت کور بصورت توکار (Build in) وجود دارد.

برای این کار در دانت کور InjectService (تزریق سرویس ها) را انجام بدهیم به سه روش ذیل عمل کنیم:

  • روش اول:AddScoped
  • روش دوم:AddSingleton
  • روش سوم:AddTransient

که برای این کار وارد فایل Startup.Cs شده و به تابع ConfigureServices می رویم و برای نمایش هر سه تا حالت در زیر من هر سه تا حالت را می نویسم بعد هر کدوم را مرحله به مرحله توضیح می دهم

  • روش AddSingleton:

در این روش یک نمونه برای همه Request در برنامه ساخته می شود یعنی برای اولین درخواست یک نمونه ایجاد می شود و برای بقیه درخواست از این نمونه استفاده می شود


نکته:
باعنایت به اینکه برنامه های وب بصورت Stateless می باشد بعد از اجرای درخواست حافظه ازاد می شود در صورت استفاده از این روش باید دقت شود که با اتمام درخواست این نمونه در برنامه از بین می رود و دیگر نمونه ای ساخته نمی شود برای مثال برنامه نویس های اماتور فکر می کنند که موقعی یک کانکشن به دیتابیس ایجاد می شود همانند برنامه های ویندوز فرم می بایستی در برنامه وب نیز به این شکل باشد که یک اشتباه بزرگ است زیرا با ورود اولین کاربر کانکشن ایجاد می شود و با خروج اولین کار کانکشن بسته شد و بقیه کاربران با خطا مواجه می شوند که بهتر است کانکشن بصورت Per Request باشد یعنی به ازای هر درخواست یک کانکشن ایجاد شود نه به اجزای کل برنامه یک کانکشن به دیتابیس داشته باشیم و همچنین نباید اجازه بدهیم که به ازای یک درخواست بیش از یک کانکشن باز شود


روش AddScope:به ازای هر درخواست برای هر کلاسی یک نمونه از اون ابجکت بساز برای مثال فرض کنید در یک درخواست ما نیاز است ده تا از یک ابجکت ساخته شود فقط یک نمونه از این ابجکت ایجاد شد و برای بقیه استفاده می شود

روش AddTransient:به ازای هر درخواست برای هر کلاس در صورت نیاز از این ابجکت به ازای هر بار نیاز یک نمونه ایجاد می شود برای مثال فرض کنید در یک درخواست در ده جا نیاز به ایجاد ابجکت هست پس ده تا از این ابجکت new می شود

بصورت خلاصه روش AddScope و AddTransient بصورت Per Request هست در روش AddScope به ازای هر درخواست یک نمونه ایجاد می شود ولی در روش AddTransient به ازای هر Request در صورت نیاز چندین نمونه ساخته می شود ولی روش AddSingleton به ازای همه درخواست Application فقط یک نمونه ساخته می شود بعبارت دیگر می توان گفت که AddScope در حقیقت AddSingleton به ازای هر درخواست می باشد

حالا برای درک بهتر ما هر دو سرویس که در این مقاله ایجاد کردیم به روش AddScope به پروژه اضافه می کنیم

وارد کنترلر شده و بصورت تابع سازنده سرویس را تزریق می کنیم

و در داخل MyService نیز به شکل زیر باز از طریق تابع سازنده تزریق وابستگی می کنیم

توجه شود برای کش شدن آبجکت ها و افزایش پرفورمانس حتما ابجکت های از نوع Readonly تعریف کنید

حالا برمی گردیم به کنترل و لطفا به نحوه فراخوانی سرویس دقت کیند

در Action مربوط به index ما نیاز به یک myservice داریم چون در ConfigureServices تعریف کردیم یک نمونه از ان بصورت اتوماتیک ایجاد می شود در هنگام ایجاد myservice دقت کنید

نیاز به سرویس sampleService می باشد که با توجه به اینکه ConfigureServices تعریف کردیم یک نمونه از ان ایجاد شده و تحویل myservice شده و سپس یک نمونه از myservice ایجاد می شود

بعبارتی ما در این حالت نیازمند ایجاد نمونه نمی باشیم و خود دانت کور وظیفه ایجاد نمونه با توجه به وابستگی ها را بر عهده می گیرد.

سورس پروژه را می تونید از روی گیت هات بنده دانلود کنید

https://github.com/javadjahangiriniopdc/DependencyInjectionWebApp



باتشکر از مطالعه این مقاله,مثل همیشه کنجکاوباشید!!!

در دوره های آموزش تضمینی مجتمع فنی ارومیه که به صورت خصوصی و عمومی در دو شیوه حضوری و آنلاین برگزار می شود سرفصل های بسیار متنوع و کاربردی را بصورت پروژه محور آموزش داده می شود تا شخص کارآموز بتواند بلافاصله پس از اتمام این دوره در کمترین زمان ممکن وارد بازار کار شود.
آموزش تخصص ماست با ما حرفه ای شوید
جهت مشاوره با شماره 09149431772 در ارتباط باشید ...
https://www.aparat.com/javadjahangiriniopdc/playlists




آموزش DependencyInjectionتزریق وابستگیجواد جهانگیریمجتمع فنی ارومیه
بنده دارای مدارک بین المللی شبکه ,برنامه نویسی, سرورهای ویندوزی و لینوکس هستم بیش از ده سال سابقه تدریس در زمینه های یاد شده را دارم. آموزش تخصص ماست با ما حرفه ای شوید 09149431772 مجتمع فنی ارومیه
شاید از این پست‌ها خوشتان بیاید