نگار قاسمی
نگار قاسمی
خواندن ۲ دقیقه·۲ سال پیش

با حواس جمع از Transient در بلیزور استفاده کنیم!


در تزریق وابستگی به شکل Transient به ازای هر درخواست دهنده‌ی جدید، یک نمونه‌ی جدید از سرویس، توسط (Dependency injection container)DI Container ساخته می‌شود و در اختیار آن قرار می‌گیرد.

وظیفه‌ی DI Container، ایجاد یک نمونه از سرویس درخواست شده، تزریق آن به کلاس درخواست دهنده و در انتها از بین بردن یا Dispose شیء ایجاد شده از سرویس ثبت شده‌است.

ثبت یک وابستگی تزریقی به عنوان Transient باعث می شود DI Container ما به عنوان یک کارخانه برای نمونه هایی از آن نوع عمل کند. یک نمونه را نمی توان به طور خودکار به بیش از یک کلاس مصرف کننده تزریق کرد، هر نمونه تزریق شده همیشه منحصر به فرد خواهد بود.


وقتی که DI Container یک نمونه از سرویسی که به صورت Transient رجیستر شده ایجاد می‌کند آن را فراموش می‌کند. این سرویس ها زمانی توسط GC جمع آوری می‌شود که سرویس هایی که درون آن رجیستر شده اند جمع آوری شوند.

برای اینکه برنامه نویسان نگران dispose کردن سرویس های رجیستر شده نباشند، هنگامی که کانتینر Dispose می‌شود متد Dispose همه سرویس هایی که IDisposable را Impelement کرده اند را Call می‌کند.

برای اینکه بتواند این کار را انجام دهد، وقتی که نمونه ای از یک سرویس که IDisposable را پیاده سازی کرده است را ایجاد می‌کند، یک رفرنس به این سرویس را در خود نگه می‌دارد.

اشیاء Transient معمولاً زمانی برای جمع‌آوری زباله واجد شرایط هستند که شیئی که به آن تزریق شده است برای جمع‌آوری زباله واجد شرایط باشد. مگر اینکه IDisposable را پیاده سازی کرده باشد. که در این حالت یک رفرنس به این نمونه در Container نگه داری می‌شود. بنابراین زمانی کاندید جمع آوری شدن توسط GC می‌باشد که Container توسط GC جمع آوری شود.

و Container تا زمانی که کاربر برگه برنامه Blazor را نبندد توسط GC جمع آوری نخواهد شد. و این به این معنی خواهد بود که علاوه بر این که با هر درخواست یک نمونه از شی که به صورت Transient رجیستر شده است ایجاد می‌شود، رفرنس ها هم تا پایان در Container نگه داری خواهد شد و اینجاست که Memory leak رخ می‌دهد!

بنابراین اگر می‌خواهید وابستگی‌ها را به‌عنوان Transient ثبت کنید، از انجام این کار برای کلاس‌هایی که IDisposable را به طور کامل پیاده‌سازی می‌کنند اجتناب کنید.

?نسخه کامل این مطلب را می‌توانید در این لینک مطالعه کنید.


di containerTransientdependency injectionblazor
شاید از این پست‌ها خوشتان بیاید