Ohjelmointi

Kuinka käyttää ohjauksen inversiota C #: ssä

Sekä ohjauksen inversio että riippuvuusinjektio mahdollistavat sovellusten komponenttien välisten riippuvuuksien erottamisen ja helpottavat sovelluksen testaamista ja ylläpitämistä. Kontrollin kääntäminen ja riippuvuusinjektio eivät kuitenkaan ole samat - näiden kahden välillä on hienovaraisia ​​eroja.

Tässä artikkelissa tarkastelemme ohjauskuvion inversiota ja ymmärrämme, miten se eroaa riippuvuuden injektoinnista asiaankuuluvien koodiesimerkkien kanssa C #: ssä.

Jotta voit työskennellä tässä artikkelissa annettujen koodiesimerkkien kanssa, järjestelmässäsi on oltava asennettuna Visual Studio 2019. Jos sinulla ei vielä ole kopiota, voit ladata Visual Studio 2019 täältä.

Luo konsolisovellusprojekti Visual Studiossa

Ensinnäkin, luodaan .NET Core -konsolisovellusprojekti Visual Studiossa. Olettaen, että Visual Studio 2019 on asennettu järjestelmään, luo uusi .NET Core -konsolisovellusprojekti Visual Studiossa noudattamalla seuraavia ohjeita.

  1. Käynnistä Visual Studio IDE.
  2. Napsauta Luo uusi projekti.
  3. Valitse Luo uusi projekti -ikkunassa ”Console App (.NET Core)” näytetystä malliluettelosta.
  4. Napsauta Seuraava.
  5. Määritä seuraavan projektin nimi ja sijainti uuden Konfiguroi uusi projekti -ikkunassa.
  6. Napsauta Luo.

Tämä luo uuden .NET Core -konsolisovellusprojektin Visual Studio 2019: ssä. Tutkimme tämän projektin hallinnan kääntämistä tämän artikkelin seuraavissa osissa.

Mikä on kontrollin kääntäminen?

Ohjauksen kääntäminen (IoC) on suunnittelumalli, jossa ohjelman ohjausvirta käännetään ylösalaisin. Voit hyödyntää ohjauskuvion inversiota irrottaaksesi sovelluksesi komponentit, vaihtaa riippuvuustoteutuksia, pilkkaamaan riippuvuuksia ja tekemään sovelluksestasi modulaarisen ja testattavan.

Riippuvuussyöttö on ohjausjoukon käänteisen osajoukko. Toisin sanoen riippuvuusinjektio on vain yksi tapa toteuttaa käänteinen hallinta. Voit myös toteuttaa ohjauksen kääntämisen esimerkiksi tapahtumien, edustajien, mallikuvion, tehdasmenetelmän tai palvelun paikannimen avulla.

Ohjaussuunnittelukuvion kääntäminen väittää, että objektien ei tulisi luoda objekteja, joista ne riippuvat jonkin toiminnan suorittamisesta. Sen sijaan heidän pitäisi hankkia nämä esineet ulkopuolisesta palvelusta tai kontista. Idea on samanlainen kuin Hollywood-periaate, jonka mukaan "Älä soita meille, soitamme sinulle". Esimerkkinä sen sijaan, että sovellus kutsuisi menetelmiä kehykseen, kehys kutsuisi sovelluksen tarjoaman toteutuksen.

Kontrolliesimerkin kääntäminen C #: een

Oletetaan, että rakennat tilausten käsittelysovellusta ja haluat toteuttaa kirjaamisen. Oletetaan yksinkertaisuuden vuoksi, että lokikohde on tekstitiedosto. Valitse juuri luomasi konsolisovellus Solution Explorer -ikkunassa ja luo kaksi tiedostoa, nimeltään ProductService.cs ja FileLogger.cs.

  julkisen luokan ProductService

    {

yksityinen vain luku FileLogger _fileLogger = uusi FileLogger ();

public void Loki (merkkijono)

        {

_fileLogger.Log (viesti);

        }

    }

julkisen luokan FileLogger

    {

public void Loki (merkkijono)

        {

Console.WriteLine ("FileLoggerin sisäisen lokin menetelmä.");

LogToFile (viesti);

        }

private void LogToFile (merkkijonoviesti)

        {

Console.WriteLine ("Menetelmä: LogToFile, Teksti: {0}", viesti);

        }

    }

Edellisessä koodinpätkässä esitetty toteutus on oikea, mutta siinä on rajoituksia. Sinun on pakko kirjata tietoja vain tekstitiedostoon. Et voi mitenkään kirjata tietoja muihin tietolähteisiin tai erilaisiin lokikohteisiin.

Joustamaton tiedonkeruun toteutus

Entä jos haluat kirjautua datatietokantataulukkoon? Nykyinen toteutus ei tue tätä ja sinun on pakko muuttaa toteutusta. Voit muuttaa FileLogger-luokan toteutusta tai luoda uuden luokan, esimerkiksi DatabaseLogger.

    julkisen luokan DatabaseLogger

    {

public void Loki (merkkijono)

        {

Console.WriteLine ("DatabaseLoggerin sisäisen lokin menetelmä.");

LogToDatabase (viesti);

        }

private void LogToDatabase (merkkijonoviesti)

        {

Console.WriteLine ("Menetelmä: LogToDatabase, Teksti: {0}", viesti);

        }

    }

Voit jopa luoda DatabaseLogger-luokan ilmentymän ProductService-luokkaan, kuten alla olevassa koodinpätkässä näkyy.

julkisen luokan ProductService

    {

yksityinen vain luku FileLogger _fileLogger = uusi FileLogger ();

yksityinen vain luku DatabaseLogger _databaseLogger =

uusi DatabaseLogger ();

public void LogToFile (merkkijonoviesti)

        {

_fileLogger.Log (viesti);

        }

public void LogToDatabase (merkkijonoviesti)

        {

_fileLogger.Log (viesti);

        }

    }

Vaikka tämä toimisi, entä jos sinun on kirjattava sovelluksesi tiedot EventLogiin? Suunnittelusi ei ole joustava, ja sinun on vaihdettava ProductService-luokkaa aina, kun sinun on kirjauduttava uuteen lokikohteeseen. Tämä ei ole vain hankalaa, vaan myös tekee ProductService-luokan hallitsemisesta erittäin vaikeaa ajan myötä.

Lisää joustavuutta käyttöliittymän avulla

Ratkaisu tähän ongelmaan on käyttää käyttöliittymää, jonka konkreettiset puunkorjuuluokat toteuttavat. Seuraava koodinpätkä näyttää käyttöliittymän nimeltä ILogger. Tämän käyttöliittymän toteuttaisivat kaksi konkreettista luokkaa FileLogger ja DatabaseLogger.

julkinen käyttöliittymä ILogger

{

void Log (merkkijonoviesti);

}

Päivitetyt versiot FileLogger- ja DatabaseLogger-luokista ovat alla.

julkinen luokka FileLogger: ILogger

    {

public void Loki (merkkijono)

        {

Console.WriteLine ("FileLoggerin sisäisen lokin menetelmä".);

LogToFile (viesti);

        }

private void LogToFile (merkkijonoviesti)

        {

Console.WriteLine ("Menetelmä: LogToFile, Teksti: {0}", viesti);

        }

    }

julkisen luokan DatabaseLogger: ILogger

    {

public void Loki (merkkijono)

        {

Console.WriteLine ("DatabaseLoggerin sisäisen lokin menetelmä.");

LogToDatabase (viesti);

        }

private void LogToDatabase (merkkijonoviesti)

        {

Console.WriteLine ("Menetelmä: LogToDatabase, Teksti: {0}", viesti);

        }

    }

Voit nyt käyttää tai muuttaa ILogger-käyttöliittymän konkreettista toteutusta tarvittaessa. Seuraava koodinpätkä näyttää ProductService-luokan, jossa on lokitapa.

julkisen luokan ProductService

    {

public void Loki (merkkijono)

        {

ILogger logger = uusi FileLogger ();

logger.Log (viesti);

        }

    }

Toistaiseksi niin hyvä. Entä jos kuitenkin haluat käyttää DatabaseLoggeria FileLoggerin sijasta ProductService-luokan Loki-menetelmässä? Voit muuttaa lokimenetelmän toteutusta ProductService-luokassa vastaamaan vaatimusta, mutta se ei tee suunnittelusta joustavaa. Tehdään nyt suunnittelusta joustavampi käyttämällä ohjauksen inversiota ja riippuvuussyöttöä.

Käännä ohjaus kääntämällä riippuvuusinjektiota

Seuraava koodinpätkä kuvaa, kuinka voit hyödyntää riippuvuusinjektiota ohittaaksesi konkreettisen kirjaajan luokan ilmentymän konstruktorinsyötöllä.

julkisen luokan ProductService

    {

yksityinen vain luku ILogger _logger;

julkinen ProductService (ILogger-kirjaaja)

        {

_logger = kirjaaja;

        }

public void Loki (merkkijono)

        {

_logger.Log (viesti);

        }

    }

Katsotaan lopuksi, kuinka voimme siirtää ILogger-käyttöliittymän toteutuksen ProductService-luokalle. Seuraava koodinpätkä näyttää, kuinka voit luoda FileLogger-luokan ilmentymän ja käyttää konstruktorin injektiota riippuvuuden välittämiseen.

staattinen void Main (merkkijono [] args)

{

ILogger logger = uusi FileLogger ();

ProductService productService = uusi ProductService (kirjaaja);

productService.Log ("Hei maailma!");

}

Tällöin olemme kääntäneet kontrollin. ProductService-luokka ei ole enää vastuussa ILogger-rajapinnan toteutuksen esiintymän luomisesta tai edes päätöksestä, mitä ILogger-rajapinnan toteutusta tulisi käyttää.

Ohjauksen kääntäminen ja riippuvuussyöttö auttavat sinua esineidesi automaattisessa pika- ja elinkaarihallinnossa. ASP.NET Core sisältää yksinkertaisen, sisäänrakennetun ohjaussäiliön kääntämisen rajoitetuilla ominaisuuksilla. Voit käyttää tätä sisäänrakennettua IoC-säilöä, jos tarpeesi ovat yksinkertaiset, tai käyttää kolmannen osapuolen säilöä, jos haluat hyödyntää lisäominaisuuksia.

Voit lukea lisää siitä, miten hallinnan inversio ja riippuvuusinjektio toimivat ASP.NET Core -palvelussa aikaisemmasta postista täältä.