Προγραμματισμός

Πώς να χρησιμοποιήσετε την αντιστροφή του ελέγχου στο 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 #

Ας υποθέσουμε ότι δημιουργείτε μια εφαρμογή επεξεργασίας παραγγελιών και θέλετε να εφαρμόσετε την καταγραφή. Για λόγους απλότητας, ας υποθέσουμε ότι ο στόχος καταγραφής είναι ένα αρχείο κειμένου. Επιλέξτε το έργο εφαρμογής κονσόλας που μόλις δημιουργήσατε στο παράθυρο του Solution Explorer και δημιουργήστε δύο αρχεία, με το όνομα ProductService.cs και FileLogger.cs.

  ProductService δημόσιας τάξης

    {

ιδιωτικό μόνο για ανάγνωση FileLogger _fileLogger = νέο FileLogger ();

δημόσιο άκυρο αρχείο καταγραφής (μήνυμα συμβολοσειράς)

        {

_fileLogger.Log (μήνυμα);

        }

    }

δημόσιο μάθημα FileLogger

    {

δημόσιο άκυρο αρχείο καταγραφής (μήνυμα συμβολοσειράς)

        {

Console.WriteLine ("Μέθοδος Inside Log του FileLogger.");

LogToFile (μήνυμα);

        }

ιδιωτικό κενό LogToFile (μήνυμα συμβολοσειράς)

        {

Console.WriteLine ("Μέθοδος: LogToFile, Κείμενο: {0}", μήνυμα);

        }

    }

Η εφαρμογή που εμφανίζεται στο προηγούμενο απόσπασμα κώδικα είναι σωστή, αλλά υπάρχει ένας περιορισμός. Είστε υποχρεωμένοι να καταγράφετε δεδομένα μόνο σε ένα αρχείο κειμένου. Δεν μπορείτε με κανέναν τρόπο να καταγράψετε δεδομένα σε άλλες πηγές δεδομένων ή διαφορετικούς στόχους καταγραφής.

Μια άκαμπτη υλοποίηση της καταγραφής

Τι γίνεται αν θέλετε να καταγράψετε δεδομένα σε έναν πίνακα βάσης δεδομένων; Η υπάρχουσα εφαρμογή δεν θα το υποστηρίζει και θα είστε υποχρεωμένοι να αλλάξετε την εφαρμογή. Θα μπορούσατε να αλλάξετε την εφαρμογή της κλάσης FileLogger ή να δημιουργήσετε μια νέα τάξη, ας πούμε, DatabaseLogger.

    Δημόσια τάξη DatabaseLogger

    {

δημόσιο άκυρο αρχείο καταγραφής (μήνυμα συμβολοσειράς)

        {

Console.WriteLine ("Μέθοδος Inside Log του DatabaseLogger.");

LogToDatabase (μήνυμα);

        }

ιδιωτικό κενό LogToDatabase (μήνυμα συμβολοσειράς)

        {

Console.WriteLine ("Μέθοδος: LogToDatabase, Text: {0}", μήνυμα);

        }

    }

Μπορείτε ακόμη και να δημιουργήσετε μια παρουσία της κλάσης DatabaseLogger μέσα στην κλάση ProductService, όπως φαίνεται στο παρακάτω απόσπασμα κώδικα.

ProductService δημόσιας τάξης

    {

ιδιωτικό μόνο για ανάγνωση FileLogger _fileLogger = νέο FileLogger ();

ιδιωτικό readonly DatabaseLogger _databaseLogger =

νέο DatabaseLogger ();

public void LogToFile (μήνυμα συμβολοσειράς)

        {

_fileLogger.Log (μήνυμα);

        }

public void LogToDatabase (μήνυμα συμβολοσειράς)

        {

_fileLogger.Log (μήνυμα);

        }

    }

Ωστόσο, αν και αυτό θα λειτουργούσε, τι γίνεται αν χρειαστεί να καταγράψετε τα δεδομένα της εφαρμογής σας στο EventLog; Το σχέδιό σας δεν είναι ευέλικτο και θα είστε υποχρεωμένοι να αλλάζετε την κλάση ProductService κάθε φορά που χρειάζεται να συνδεθείτε σε έναν νέο στόχο καταγραφής. Αυτό δεν είναι μόνο δυσκίνητο, αλλά θα σας κάνει εξαιρετικά δύσκολο να διαχειριστείτε την κλάση ProductService με την πάροδο του χρόνου.

Προσθέστε ευελιξία με μια διεπαφή

Η λύση σε αυτό το πρόβλημα είναι να χρησιμοποιήσετε μια διεπαφή που θα εφαρμόζουν οι συγκεκριμένες κλάσεις καταγραφέα. Το παρακάτω απόσπασμα κώδικα εμφανίζει μια διεπαφή που ονομάζεται ILogger. Αυτή η διεπαφή θα εφαρμοστεί από τις δύο συγκεκριμένες κατηγορίες FileLogger και DatabaseLogger.

δημόσια διεπαφή ILogger

{

void Log (μήνυμα συμβολοσειράς).

}

Οι ενημερωμένες εκδόσεις των κατηγοριών FileLogger και DatabaseLogger δίνονται παρακάτω.

δημόσια τάξη FileLogger: ILogger

    {

δημόσιο άκυρο αρχείο καταγραφής (μήνυμα συμβολοσειράς)

        {

Console.WriteLine ("Μέθοδος Inside Log του FileLogger.");

LogToFile (μήνυμα);

        }

ιδιωτικό κενό LogToFile (μήνυμα συμβολοσειράς)

        {

Console.WriteLine ("Μέθοδος: LogToFile, Κείμενο: {0}", μήνυμα);

        }

    }

Δημόσια τάξη DatabaseLogger: ILogger

    {

δημόσιο άκυρο αρχείο καταγραφής (μήνυμα συμβολοσειράς)

        {

Console.WriteLine ("Μέθοδος Inside Log του DatabaseLogger.");

LogToDatabase (μήνυμα);

        }

ιδιωτικό κενό LogToDatabase (μήνυμα συμβολοσειράς)

        {

Console.WriteLine ("Μέθοδος: LogToDatabase, Text: {0}", μήνυμα);

        }

    }

Τώρα μπορείτε να χρησιμοποιήσετε ή να αλλάξετε τη συγκεκριμένη εφαρμογή της διεπαφής ILogger όποτε είναι απαραίτητο. Το ακόλουθο απόσπασμα κώδικα εμφανίζει την κλάση ProductService με εφαρμογή της μεθόδου καταγραφής.

ProductService δημόσιας τάξης

    {

δημόσιο άκυρο αρχείο καταγραφής (μήνυμα συμβολοσειράς)

        {

ILogger logger = νέο FileLogger ();

logger.Log (μήνυμα);

        }

    }

Μέχρι εδώ καλά. Ωστόσο, τι γίνεται αν θέλετε να χρησιμοποιήσετε το DatabaseLogger αντί του FileLogger στη μέθοδο καταγραφής της κλάσης ProductService; Θα μπορούσατε να αλλάξετε την εφαρμογή της μεθόδου καταγραφής στην κλάση ProductService για να ικανοποιήσετε την απαίτηση, αλλά αυτό δεν καθιστά το σχεδιασμό ευέλικτο. Ας κάνουμε τώρα το σχεδιασμό πιο ευέλικτο χρησιμοποιώντας αντιστροφή έγχυσης ελέγχου και εξάρτησης.

Αναστρέψτε τον έλεγχο χρησιμοποιώντας ένεση εξάρτησης

Το παρακάτω απόσπασμα κώδικα απεικονίζει πώς μπορείτε να επωφεληθείτε από την έγχυση εξάρτησης για να περάσετε μια παρουσία συγκεκριμένης κλάσης καταγραφικού χρησιμοποιώντας έγχυση κατασκευαστή.

ProductService δημόσιας τάξης

    {

ιδιωτικό αναγνωστικό ILOGger _logger;

δημόσια ProductService (ILogger logger)

        {

_logger = καταγραφέας;

        }

δημόσιο άκυρο αρχείο καταγραφής (μήνυμα συμβολοσειράς)

        {

_logger.Log (μήνυμα);

        }

    }

Τέλος, ας δούμε πώς μπορούμε να περάσουμε μια εφαρμογή της διεπαφής ILogger στην κλάση ProductService. Το ακόλουθο απόσπασμα κώδικα δείχνει πώς μπορείτε να δημιουργήσετε μια παρουσία της κλάσης FileLogger και να χρησιμοποιήσετε την έγχυση κατασκευαστή για να περάσετε την εξάρτηση.

static void Main (συμβολοσειρά [] args)

{

ILogger logger = νέο FileLogger ();

ProductService productService = νέο ProductService (καταγραφέας);

productService.Log ("Hello World!");

}

Με αυτόν τον τρόπο, έχουμε αντιστρέψει τον έλεγχο. Η κλάση ProductService δεν είναι πλέον υπεύθυνη για τη δημιουργία μιας εμφάνισης μιας εφαρμογής της διεπαφής ILogger ή ακόμη και για να αποφασίσει ποια εφαρμογή της διεπαφής ILogger θα πρέπει να χρησιμοποιηθεί.

Η αντιστροφή της έγχυσης ελέγχου και εξάρτησης σάς βοηθά με την αυτόματη εγκατάσταση και διαχείριση του κύκλου ζωής των αντικειμένων σας. Το ASP.NET Core περιλαμβάνει μια απλή, ενσωματωμένη αντιστροφή κοντέινερ ελέγχου με περιορισμένο σύνολο χαρακτηριστικών. Μπορείτε να χρησιμοποιήσετε αυτό το ενσωματωμένο κοντέινερ IoC εάν οι ανάγκες σας είναι απλές ή να χρησιμοποιήσετε ένα κοντέινερ τρίτων, εάν θέλετε να αξιοποιήσετε επιπλέον δυνατότητες.

Μπορείτε να διαβάσετε περισσότερα σχετικά με τον τρόπο εργασίας με την αντιστροφή της έγχυσης ελέγχου και εξάρτησης στο ASP.NET Core στην προηγούμενη ανάρτησή μου εδώ.