Programavimas

Kaip naudoti valdymo inversiją C #

Valdymo inversija ir priklausomybės injekcija leidžia nutraukti priklausomybes tarp programos komponentų ir palengvinti jūsų programos testavimą ir priežiūrą. Tačiau valdymo inversija ir priklausomybės injekcija nėra tas pats - tarp jų yra subtilių skirtumų.

Šiame straipsnyje mes išnagrinėsime valdymo modelio inversiją ir suprasime, kuo jis skiriasi nuo priklausomybės injekcijos, naudodami atitinkamus kodų pavyzdžius C #.

Norėdami dirbti su šiame straipsnyje pateiktais kodų pavyzdžiais, sistemoje turite būti įdiegę „Visual Studio 2019“. Jei dar neturite kopijos, galite atsisiųsti „Visual Studio 2019“ čia.

„Visual Studio“ sukurkite konsolės programos projektą

Pirmiausia sukurkime .NET Core konsolės programos projektą „Visual Studio“. Darant prielaidą, kad „Visual Studio 2019“ yra įdiegta jūsų sistemoje, atlikite toliau nurodytus veiksmus, kad sukurtumėte naują .NET Core konsolės programos projektą „Visual Studio“.

  1. Paleiskite „Visual Studio IDE“.
  2. Spustelėkite „Sukurti naują projektą“.
  3. Lange „Kurti naują projektą“ iš rodomų šablonų sąrašo pasirinkite „Console App (.NET Core)“.
  4. Spustelėkite Pirmyn.
  5. Tada rodomame lange „Konfigūruoti naują projektą“ nurodykite naujo projekto pavadinimą ir vietą.
  6. Spustelėkite Sukurti.

Tai sukurs naują „.NET Core“ konsolės programos projektą „Visual Studio 2019“. Mes naudosime šį projektą, kad ištirtume valdymo inversiją tolesniuose šio straipsnio skyriuose.

Kas yra valdymo inversija?

Valdymo inversija (IoC) yra projektavimo modelis, kuriame apverstas programos valdymo srautas. Norėdami pasinaudoti valdymo modelio inversija, galite atsieti savo programos komponentus, sukeisti priklausomybės diegimą, pajuokti priklausomybes ir padaryti savo programą modulinę ir patikrinamą.

Priklausomybės injekcija yra valdymo principo inversijos pogrupis. Kitaip tariant, priklausomybės injekcija yra tik vienas iš valdymo inversijos įgyvendinimo būdų. Taip pat galite įdiegti valdymo inversiją naudodami, pavyzdžiui, įvykius, delegatus, šablono šabloną, gamyklos metodą ar paslaugų lokatorių.

Valdymo dizaino modelio inversija teigia, kad objektai neturėtų kurti objektų, nuo kurių jie priklauso atlikti tam tikrą veiklą. Jie turėtų tuos objektus gauti iš išorės tarnybos ar konteinerio. Idėja yra analogiška Holivudo principui, kuris sako: „Neskambink mums, mes jums paskambinsime“. Pavyzdžiui, vietoj to, kad programa kviestų metodus sistemoje, sistema vadintų diegimą, kurį pateikė programa.

Valdymo pavyzdžio inversija C #

Tarkime, kad kuriate užsakymų apdorojimo programą ir norėtumėte įgyvendinti registravimą. Paprastumo sumetimais tarkime, kad žurnalo tikslas yra tekstinis failas. Lange „Solution Explorer“ pasirinkite ką tik sukurtą konsolės programos projektą ir sukurkite du failus, pavadintus „ProductService.cs“ ir „FileLogger.cs“.

  viešosios klasės „ProductService“

    {

privatus, tik skaitomas FileLogger _fileLogger = new FileLogger ();

public void žurnalas (eilutės pranešimas)

        {

_fileLogger.Log (pranešimas);

        }

    }

viešosios klasės „FileLogger“

    {

public void žurnalas (eilutės pranešimas)

        {

Console.WriteLine ("Inside Log metodas FileLogger.");

„LogToFile“ (pranešimas);

        }

private void „LogToFile“ (eilutės pranešimas)

        {

Console.WriteLine ("Metodas: LogToFile, Tekstas: {0}", pranešimas);

        }

    }

Ankstesniame kodo fragmente pateiktas diegimas yra teisingas, tačiau tam yra apribojimas. Jūs privalote registruoti duomenis tik tekstiniame faile. Jokiu būdu negalite registruoti duomenų į kitus duomenų šaltinius ar skirtingus žurnalo taikinius.

Lankstus kirtimų įgyvendinimas

Ką daryti, jei norite registruoti duomenis į duomenų bazės lentelę? Esamas diegimas to nepalaikys ir būsite priversti pakeisti įgyvendinimą. Galite pakeisti „FileLogger“ klasės įgyvendinimą arba sukurti naują klasę, tarkime, „DatabaseLogger“.

    viešosios klasės „DatabaseLogger“

    {

public void žurnalas (eilutės pranešimas)

        {

Console.WriteLine („Vidinio žurnalo„ DatabaseLogger “metodas“);

„LogToDatabase“ (pranešimas);

        }

private void „LogToDatabase“ (eilutės pranešimas)

        {

Console.WriteLine ("Metodas: LogToDatabase, Tekstas: {0}", pranešimas);

        }

    }

Jūs netgi galite sukurti „DatabaseLogger“ klasės egzempliorių „ProductService“ klasėje, kaip parodyta žemiau esančiame kodo fragmente.

viešosios klasės „ProductService“

    {

privatus tik skaitomas FileLogger _fileLogger = new FileLogger ();

privatus tik skaitomas DatabaseLogger _databaseLogger =

nauja „DatabaseLogger“ ();

public void „LogToFile“ (eilutės pranešimas)

        {

_fileLogger.Log (pranešimas);

        }

public void „LogToDatabase“ (eilutės pranešimas)

        {

_fileLogger.Log (pranešimas);

        }

    }

Tačiau, nors tai ir pasiteisintų, ką daryti, jei jums reikia prisijungti savo programos duomenis į „EventLog“? Jūsų dizainas nėra lankstus ir būsite priversti pakeisti „ProductService“ klasę kiekvieną kartą, kai reikės prisijungti prie naujo žurnalo taikymo. Tai ne tik sudėtinga, bet ir labai apsunkins laiko valdymą „ProductService“ klasėje.

Pridėkite lankstumo naudodami sąsają

Šios problemos sprendimas yra naudoti sąsają, kurią įdiegtų betono kaupimo klasės. Šis kodo fragmentas rodo sąsają, vadinamą ILogger. Šią sąsają įgyvendins dvi konkrečios klasės „FileLogger“ ir „DatabaseLogger“.

viešoji sąsaja ILogger

{

negaliojantis žurnalas (eilutės pranešimas);

}

Toliau pateikiamos atnaujintos „FileLogger“ ir „DatabaseLogger“ klasių versijos.

viešoji klasė FileLogger: ILogger

    {

public void žurnalas (eilutės pranešimas)

        {

Console.WriteLine ("Inside Log metodas FileLogger.");

„LogToFile“ (pranešimas);

        }

private void „LogToFile“ (eilutės pranešimas)

        {

Console.WriteLine ("Metodas: LogToFile, Tekstas: {0}", pranešimas);

        }

    }

viešosios klasės duomenų bazė „Logger“: „ILogger“

    {

public void žurnalas (eilutės pranešimas)

        {

Console.WriteLine („Vidinio žurnalo„ DatabaseLogger “metodas“);

„LogToDatabase“ (pranešimas);

        }

private void „LogToDatabase“ (eilutės pranešimas)

        {

Console.WriteLine ("Metodas: LogToDatabase, Tekstas: {0}", pranešimas);

        }

    }

Dabar, kai reikia, galite naudoti arba pakeisti konkretų „ILogger“ sąsajos įgyvendinimą. Šis kodo fragmentas rodo „ProductService“ klasę su žurnalo metodo įgyvendinimu.

viešosios klasės „ProductService“

    {

public void žurnalas (eilutės pranešimas)

        {

ILogger logger = naujas FileLogger ();

logger.Log (pranešimas);

        }

    }

Kol kas viskas gerai. Tačiau ką daryti, jei norite naudoti „DatabaseLogger“ vietoj „FileLogger“ „ProductService“ klasės žurnalo metodo? Galite pakeisti „Log“ metodo įgyvendinimą „ProductService“ klasėje, kad atitiktų reikalavimus, tačiau tai nepadaro dizaino lankstaus. Padarykime dizainą lankstesnį, naudodami valdymo inversiją ir priklausomybės įpurškimą.

Apverskite kontrolę naudodami priklausomybės injekciją

Šis kodo fragmentas parodo, kaip galite pasinaudoti priklausomybės įpurškimo pranašumais, kad perduotumėte konkretaus medienos ruošos klasės egzempliorių naudodami konstruktoriaus įpurškimą.

viešosios klasės „ProductService“

    {

privatus tik skaitomas ILogger _logger;

viešoji „ProductService“ („ILogger logger“)

        {

_logger = logger;

        }

public void žurnalas (eilutės pranešimas)

        {

_logger.Log (pranešimas);

        }

    }

Galiausiai pažiūrėkime, kaip mes galime perduoti „ILogger“ sąsajos įgyvendinimą „ProductService“ klasei. Šis kodo fragmentas parodo, kaip galite sukurti „FileLogger“ klasės egzempliorių ir naudoti konstruktoriaus injekciją, kad perduotumėte priklausomybę.

static void Main (string [] args)

{

ILogger logger = naujas FileLogger ();

ProductService productService = nauja ProductService (kaupiklis);

productService.Log („Sveikas pasaulis!“);

}

Tai darydami mes apvertėme kontrolę. „ProductService“ klasė nebėra atsakinga už „ILogger“ sąsajos diegimo egzemplioriaus sukūrimą ar net sprendimą, kuris „ILogger“ sąsajos diegimas turėtų būti naudojamas.

Valdymo inversija ir priklausomybės įpurškimas padeda jums atlikti automatinį objektų greitinimą ir gyvavimo ciklą. ASP.NET Core apima paprastą, įmontuotą valdymo konteinerio inversiją su ribotu funkcijų rinkiniu. Galite naudoti šį įmontuotą IoC talpyklą, jei jūsų poreikiai yra paprasti, arba naudoti trečiosios šalies talpyklą, jei norite pasinaudoti papildomomis funkcijomis.

Daugiau apie tai, kaip dirbti su valdymo inversija ir priklausomybės įpurškimu, galite perskaityti ASP.NET Core mano ankstesniame įraše čia.