כיצד להשתמש בהיפוך שליטה ב- C #

הן היפוך שליטה והן הזרקת תלות מאפשרים לך לשבור תלות בין הרכיבים ביישום שלך ולהקל על היישום שלך לבדיקה ולתחזוקה. עם זאת, היפוך שליטה והזרקת תלות אינם זהים - ישנם הבדלים עדינים בין השניים.

במאמר זה נבחן את ההיפוך של דפוס השליטה ונבין כיצד הוא שונה מהזרקת תלות עם דוגמאות קוד רלוונטיות ב- C #.

כדי לעבוד עם דוגמאות הקוד המופיעות במאמר זה, עליך להתקין במערכת Visual Studio 2019 שלך. אם עדיין אין לך עותק, תוכל להוריד את Visual Studio 2019 כאן. 

צור פרויקט יישום קונסולה ב- Visual Studio

ראשית, בואו ניצור פרויקט יישומי קונסולת .NET Core ב- Visual Studio. בהנחה ש- Visual Studio 2019 מותקן במערכת שלך, בצע את הצעדים המתוארים להלן כדי ליצור פרויקט יישום חדש של מסוף ה- NET Core ב- Visual Studio.

  1. הפעל את Visual Studio IDE.
  2. לחץ על "צור פרויקט חדש".
  3. בחלון "צור פרויקט חדש" בחר "יישום קונסולה (.NET Core)" מרשימת התבניות המוצגות.
  4. הקש "הבא. 
  5. בחלון "הגדר את הפרויקט החדש שלך" שמוצג הבא, ציין את השם והמיקום של הפרויקט החדש.
  6. לחץ על צור. 

פעולה זו תיצור פרויקט יישום קונסולת .NET Core חדש ב- Visual Studio 2019. נשתמש בפרויקט זה כדי לחקור היפוך שליטה בחלקים הבאים במאמר זה.

מהי היפוך שליטה?

היפוך שליטה (IoC) הוא תבנית עיצוב בה זרימת הבקרה של התוכנית הופכת. אתה יכול לנצל את ההיפוך של דפוס השליטה כדי לפרק את רכיבי היישום שלך, להחליף יישומי תלות, לתלות מדומה ולהפוך את היישום שלך למודולרי ולבדוק.

הזרקת תלות היא קבוצת משנה של עקרון היפוך השליטה. במילים אחרות, הזרקת תלות היא רק דרך אחת ליישום היפוך שליטה. ניתן גם ליישם היפוך שליטה באמצעות אירועים, נציגים, תבנית תבנית, שיטת מפעל או איתור שירותים, למשל.

ההיפוך של דפוס תכנון השליטה קובע כי עצמים לא צריכים ליצור אובייקטים שהם תלויים בהם כדי לבצע פעילות כלשהי. במקום זאת, עליהם לקבל חפצים אלה משירות חיצוני או מכולה. הרעיון מקביל לעיקרון ההוליוודי שאומר, "אל תתקשר אלינו, אנחנו נתקשר אליך." כדוגמה, במקום שהיישום יקרא לשיטות במסגרת, המסגרת תקרא ליישום שניתן על ידי היישום. 

היפוך לדוגמא שליטה ב- C #

נניח שאתה בונה יישום לעיבוד הזמנות ותרצה ליישם רישום. למען הפשטות, נניח כי יעד היומן הוא קובץ טקסט. בחר את פרויקט יישום המסוף שיצרת זה עתה בחלון סייר הפיתרון וצור שני קבצים בשם ProductService.cs ו- FileLogger.cs.

    ProductService בכיתה ציבורית

    {

        פרטי לקריאה בלבד FileLogger _fileLogger = FileLogger חדש ();

        יומן חלל ציבורי (הודעת מחרוזת)

        {

            _fileLogger.Log (הודעה);

        }

    }

    FileLogger בכיתה ציבורית

    {

        יומן חלל ציבורי (הודעת מחרוזת)

        {

            Console.WriteLine ("שיטת היומן הפנימי של FileLogger.");

            LogToFile (הודעה);

        }

        ריק ריק LogToFile (הודעת מחרוזת)

        {

            Console.WriteLine ("שיטה: LogToFile, טקסט: {0}", הודעה);

        }

    }

היישום המוצג בקטע הקוד הקודם נכון אך קיימת מגבלה. אתה מוגבל לרישום נתונים לקובץ טקסט בלבד. אינך יכול בשום צורה להיכנס לנתונים למקורות נתונים אחרים או ליעדי יומן אחרים.

יישום לא גמיש של רישום

מה אם היית רוצה לתעד נתונים לטבלת מסדי נתונים? היישום הקיים לא יתמוך בכך ואתה נאלץ לשנות את היישום. אתה יכול לשנות את היישום של מחלקת FileLogger, או ליצור מחלקה חדשה, למשל, DatabaseLogger.

    מחלקת ציבור DatabaseLogger

    {

        יומן חלל ציבורי (הודעת מחרוזת)

        {

            Console.WriteLine ("שיטת היומן הפנימי של DatabaseLogger.");

            LogToDatabase (הודעה);

        }

        ריק ריק LogToDatabase (הודעת מחרוזת)

        {

            Console.WriteLine ("שיטה: LogToDatabase, טקסט: {0}", הודעה);

        }

    }

אתה יכול אפילו ליצור מופע של מחלקת DatabaseLogger בתוך המחלקה ProductService כפי שמוצג בקטע הקוד שלמטה.

ProductService בכיתה ציבורית

    {

        פרטי לקריאה בלבד FileLogger _fileLogger = FileLogger חדש ();

        פרטי קריאה בלבד DatabaseLogger _databaseLogger =

         DatabaseLogger חדש ();

        ריק ריק LogToFile (הודעת מחרוזת)

        {

            _fileLogger.Log (הודעה);

        }

        חלל ריק LogToDatabase (הודעת מחרוזת)

        {

            _fileLogger.Log (הודעה);

        }

    }

עם זאת, למרות שזה יעבוד, מה אם היית צריך לרשום את נתוני היישום שלך ל- EventLog? העיצוב שלך אינו גמיש ותאלץ לשנות את מחלקת ProductService בכל פעם שתצטרך להיכנס ליעד יומן חדש. זה לא רק מסורבל אלא גם יקשה עליכם לנהל את מחלקת ProductService לאורך זמן.

הוסף גמישות באמצעות ממשק 

הפיתרון לבעיה זו הוא שימוש בממשק שיישמו כיתות לוגר הבטון. קטע הקוד הבא מציג ממשק בשם ILogger. ממשק זה יושם על ידי שני הכיתות הקונקרטיות FileLogger ו- DatabaseLogger.

ממשק ציבורי ILogger

{

    בטל יומן (הודעת מחרוזת);

}

הגרסאות המעודכנות של המחלקות FileLogger ו- DatabaseLogger מפורטות להלן.

מחלקה ציבורית FileLogger: ILogger

    {

        יומן חלל ציבורי (הודעת מחרוזת)

        {

            Console.WriteLine ("שיטת היומן הפנימי של FileLogger.");

            LogToFile (הודעה);

        }

        ריק ריק LogToFile (הודעת מחרוזת)

        {

            Console.WriteLine ("שיטה: LogToFile, טקסט: {0}", הודעה);

        }

    }

מחלקת ציבור DatabaseLogger: ILogger

    {

        יומן חלל ציבורי (הודעת מחרוזת)

        {

            Console.WriteLine ("שיטת היומן הפנימי של DatabaseLogger.");

            LogToDatabase (הודעה);

        }

        ריק ריק LogToDatabase (הודעת מחרוזת)

        {

            Console.WriteLine ("שיטה: LogToDatabase, טקסט: {0}", הודעה);

        }

    }

כעת תוכל להשתמש או לשנות את היישום הקונקרטי של ממשק ILogger בכל צורך. קטע הקוד הבא מציג את המחלקה ProductService עם יישום של שיטת ה- Log.

ProductService בכיתה ציבורית

    {

        יומן חלל ציבורי (הודעת מחרוזת)

        {

            לוגר לוגר = FileLogger חדש ();

            logger.Log (הודעה);

        }

    }

בינתיים הכל טוב. עם זאת, מה אם תרצה להשתמש ב- DatabaseLogger במקום FileLogger בשיטת יומן המחלקה ProductService? אתה יכול לשנות את היישום של שיטת ה- Log במחלקה ProductService כדי לעמוד בדרישה, אך זה לא הופך את העיצוב לגמיש. בואו נעמיד כעת את העיצוב לגמיש יותר באמצעות היפוך של שליטה והזרקת תלות.

הפוך את השליטה באמצעות הזרקת תלות

קטע הקוד הבא ממחיש כיצד תוכלו לנצל את הזרקת התלות בכדי להעביר מופע של מחלקת לוגר בטון באמצעות הזרקת קונסטרוקטור.

ProductService בכיתה ציבורית

    {

        פרטי קריאה בלבד ILogger _logger;

        ProductService ציבורי (לוגר לוגר)

        {

            _ לוגר = לוגר;

        }

        יומן חלל ציבורי (הודעת מחרוזת)

        {

            _logger.Log (הודעה);

        }

    }

לבסוף, בואו נראה כיצד נוכל להעביר יישום של ממשק ILogger למחלקת ProductService. קטע הקוד הבא מראה כיצד ניתן ליצור מופע של מחלקת FileLogger ולהשתמש בהזרקת קונסטרוקטור כדי להעביר את התלות.

ריק סטטי ראשי (מחרוזת [] טענות)

{

    לוגר לוגר = FileLogger חדש ();

    ProductService productService = ProductService חדש (לוגר);

    productService.Log ("שלום עולם!");

}

בכך הפכנו את השליטה. מחלקת ProductService אינה אחראית עוד ליצירת מופע של יישום ממשק ILogger או אפילו להחליט באיזה יישום של ממשק ILogger יש להשתמש.

היפוך שליטה והזרקת תלות עוזרים לך לייצור אוטומטי וניהול מחזור החיים של האובייקטים שלך. ASP.NET Core כולל היפוך פשוט ומובנה של מיכל בקרה עם קבוצה מוגבלת של תכונות. אתה יכול להשתמש במיכל IoC המובנה הזה אם הצרכים שלך פשוטים או להשתמש במכולה של צד שלישי אם ברצונך למנף תכונות נוספות.

אתה יכול לקרוא עוד על אופן העבודה עם היפוך של שליטה והזרקת תלות ב- ASP.NET Core בפוסט הקודם שלי כאן.