تفاوت بین <GetService<T و <GetRequiredService<T

در این مقاله میخواهیم نگاهی به <GetService<T و <GetRequiredService<T که متد های پیش فرض و داخلی Di Container  خود Asp.Net Core می باشد بندازیم و در ادامه به تفاوت های بین این دو و کدام یک را باید انتخاب کنیم بپردازیم .

متد GetService<T> اگر سرویسی وجود نداشته باشد null بازگشت داده می شود و در عوض <GetRequiredService<T یک استثنا را پرتاب می کند . اگر از یک Container ثالث (Third-Party) استفاده میکنید بهتر است از <GetRequiredService<T استفاده کنید که در صورت استثنا Container  ثالث بتواند جزئیات بیشتر این استثنا را تشخیص دهد و بنابراین میتوانید نتیجه بگیرید که سرویس مورد نظر چرا ثبت (Register) نشده است .

در قلب تزریق وابستگی Asp.Net Core اینترفیس IServiceProvider قرار دارد .

public interface IServiceProvider
{
    object GetService(Type serviceType);
}

در واقع شما نباید به طور مستقیم از IServiceProvider استفاده کنید و باید به صورت استاندارد این کار را به Framework بسپارید و نگران پشت صحنه نباشد . 

نکته : 
استفاده مستفیم از IserviceProvider نمونه ای از الگوی Service Locator است که یک ضد الگو (anti-Pattern)  در نظر گرفته می شود ، زیرا وابستگی کلاس را پنهان می کند و کار نوشتن آزمون های واحد را مشکل تر می کند .

مقایسه <GetService<T و <GetRequiredService<T

<GetService<T یک شی از نوع ServiceType را برمیگرداند و یا اگر شی ای از نوع ServiceType وجود نداشته باشد Null بازگشت داده می شود .

در مقابل <GetRequiredService<T یک شی از نوع ServiceType را برمیگرداند و اگر وجود نداشته باشد InvalidOperationException را بازگشت می دهد . 

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

در نهایت باید کدام را انتخاب کرد ؟ 

شما در ابتدا باید تزریق وابستگی را از طریق سازنده کلاس انجام دهید و در غیر اینصورت اگر توسط Ioc Container پشتیبانی نشد میتوانید یکی از متد های GetService را انتخاب کنید که پیشنهاد انتخاب GetRequiredService می باشد به دلایل زیر : 

اگر از GetService استفاده کنید نیاز دارید که همیشه Null بودن را چک کنید و برای حذف این کد های تکراری بهتر است از GetRequiredService استفاده کنید که به صورت توکار بررسی می شود .

اگر بررسی Null بودن را فراموش کنید در سطر های بعدی پیدا کردن علت NullReferenceException از رسیدگی به InvalidOperationException مشکل تر خواهد بود .