
new.BooksService. צריך לומר ל-NET. ליצור את האובייקט ובאיזה scope הוא חי.builder.Services יש שלוש אפשרויות.AddTransient: האובייקט נוצר בכל שימוש ונזרק אחריו. מתאים לשימוש חד-פעמי.AddScoped: אובייקט אחד לכל request, שחי עד סוף ה-request. מתאים כאשר כמה מקומות באותו request צריכים אותו, כמו כמה קונטרולרים, או כמה פניות למסד.AddSingleton: אובייקט אחד לכל חיי ה-REST API. אם הוא מחזיק דאטה, פניות במקביל של כמה לקוחות עלולות לשבש אותו, וצריך נעילות (Locking). מתאים רק לאובייקט עם פונקציות סטטיות שלא מנהלות דאטה משותף.BooksService יש דאטה ברמת ה-Service, ולכן Singleton לא מתאים. נבחר Scoped.AddDbContext רושמת את BookstoreContext ל-DI, והוא גם כן scoped. ב-BooksService מגדירים שדה פרטי _db ומבקשים את הקונטקסט בקונסטרקטור.BooksService, ושם מבקשת BookstoreContext. היא מייצרת קודם את ה-Context, אחר כך את ה-Service ולבסוף את ה-Controller, וכל זה מחדש בכל request כדי שדאטה של לקוח אחד לא יפריע לאחר.builder.Services.AddTransient<BooksService>()builder.Services.AddScoped<BooksService>()builder.Services.AddSingleton<...>()הטקסט המלא של הדקות הראשונות בהרצאה «הסבר על Dependency Injection» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
אז בואו נבין מה זה בעצם dependency injection. dependency injection זהו מצב שבו הפריימורק שאנחנו עובדים איתה, במקרה הזה זה.NET, יוצרת לנו אובייקט ומביאה לנו אותו אם אנחנו מבקשים אותו.
איך אנחנו מבקשים את האובייקטים הללו? אנחנו מבקשים אותם בקונסטרקטור של מחלקה ש.NET יוצרת. לדוגמה,.NET יוצרת אובייקט מהקונטרולר, אז אנחנו יכולים ללכת לקונסטרקטור ולבקש את האובייקט הזה.
פה ננסה לעשות את זה. נלך ל-books-controller, נבנה סיטור, ונגיד, תקשיב, אנחנו בעצם לא רוצים לייצר אובייקט מה-service שלנו, אנחנו רוצים שכאשר.NET יוצרת אובייקט מה-controller שתביא לנו אובייקט מוכן מה-service.
כל מה שאנחנו צריכים לעשות זה להגיד, יש לנו books-service, הנה. פשוט תביא לי את האובייקט הזה, ואני לא רוצה לייצר ניהו ממנו, בואו נפטר רגע מהניהו הזה, ופשוט נבוא ונגיד, טוב, ברגע שאתה מביא לי אובייקט, אז אני אכניס אותו לאובייקט הבוקסרוויס, למשתנה בוקסרוויס שנמצא ברמת הקונטרולר.
עכשיו אתם יכולים לשאול, למה זה כזה חשוב ומשנה? מה היתרון של זה? מה זה משנה אם אני פשוט בונה אובייקט משלי, או שהסביבה נותנת לי אותו?
למה בכלל יש את הקונספט הזה? אם אנחנו בונים אובייקט משלנו על ידי new והאובייקט צריך כל מיני דברים כמו שראיתם מקודם, connection string או הגדרות או options מסוימים, אז אנחנו חייבים להתחיל לספק את כל הדברים האלה.
אם הסביבה כבר יוצרת לנו את האובייקטים, היא דואגת לספק להם את כל מה שצריך. זה יתרון אדיר וזאת שיטת עבודה מאוד פופולרית בהמון מערכות,.NET עובדים איתה מאוד חזק,.NET Core.
אז אנחנו פשוט באנו ואמרנו, ברגע שאתה יוצר אובייקט, ברגע שהסביבה יוצרת אובייקט מהקונטרולר, כמובן שצריך להיות אובייקט מהקונטרולר, בשביל שמישהו יקרא בכלל לפונקציה טסט, תביא לי את האובייקט של הסרוויס, בואו נריץ ונראה מה קורה, אני פשוט מריץ את המערכת, ואנחנו בעצם הולכים לראות שיש פה איזה משהו לא
בסדר, מה שהוא אומר לי זה יש פה איזה שגיאה, הוא אומר לי, I don't handle exception acute while processing the request, אני לא מוצליח לפתור או למצוא סרוויס שנקרא בוקס סרוויס.
מה שהוא אומר לי בגדול זה אחלה שאתה רוצה שאני אביא לך את האובייקט, אין לי אובייקט כזה. למה אתה חושב שיש לי אובייקט כזה? אין לי. זה מה שבעצם דוטנט אמרה.
ולגמרי זה נכון, כי אנחנו צריכים להגדיר עוד דבר אחד, וזה לומר לדוטנט לייצר אובייקט מבוקסרוויס ולהחליט באיזה סקופ הוא חי. בואו נראה איך עושים את זה ומה זה בכלל אומר באיזה סקופ הוא חי.
אנחנו צריכים לעשות את זה ברמת הפרוגרם. פה, יש לנו פה את הפקודה הזאת שתכף טיפה נדבר עליה. מתחת אני מבצע builder.services. ויש לי פה שלוש אפשרויות.
אפשרות ראשונה זה add transient. זה בעצם בוא תייצר אובייקט מהסוג שכרגע אני אגיד לך. הסוג שאנחנו רוצים לייצר זה books.service. בצורה כזאת.
זה מספק אני לא יוצר אובייקט new, אני פשוט אומר לו תקשיב בוא תייצר אובייקט מבוקס סרוויס, אבל השאלה היא מתי המערכת יוצרת את האובייקט ולמשך כמה זמן הוא חי.
אז מה פירוש המילה transient? transient באנגלית זה משהו שהוא זמני. כאשר אנחנו מייצרים אובייקט או אומרים לדוטנט לייצר אובייקט בעזרת add transient, אז ברגע שאנחנו נרצה להשתמש עם האובייקט הזה, מסוג Book Service, המערכת תייצר אותו רק למשך השימוש הנוכחי, ותפסיק לייצר לנו, או תיפטר ממנו.
ברגע שאני רוצה עוד פעם להשתמש איתו, אז שוב פעם המערכת תייצר אובייקט. זה פחות נכון כאשר אנחנו רוצים להשתמש באובייקט, שנרצה אולי להשתמש בו בכל מיני מקומות, במהלך Request 1.
אז במקום שהמערכת תייצר כל פעם שאני רוצה להשתמש עם האובייקט, היא תייצר אחד חדש, אנחנו יכולים לבוא ולהגיד, אוקיי, Add, AddScope זה בעצם גם כן בוא תייצר אובייקט אבל האובייקט הזה חי למשך כל הרקוויסט יכול להיות שבמהלך רקוויסט אנחנו נרצה בכל מיני מקומות להשתמש עם האובייקט או לבקש
אובייקט בכל מיני מקומות כמובן מסוג BookService כרגע אנחנו אנחנו תייצר אובייקט אחד ותיתנו רק את האובייקט הזה בסוף הרקוויסט האובייקט כבר לא יהיה פעיל האפשרות השלישית זה AddSingleTone סינגלטון בעצם אומר אני מייצר