داستان حیرت آور dependency injection در سی شارپ

dependency injection در سی شارپ
تاریخ بروزرسانی : 21 مرداد 1399 | تعداد بازدید : 6427 | زمان خواندن مقاله : 10دقیقه
سی شارپ،

در این مقاله می خواهیم درباره dependency injection در سی شارپ بحث کنیم. اما قبل از آن باید با دو مفهوم آشنا باشید: 

  1. اصل وارونگی وابستگی (Dependency Inversion Principle) یا به اختصار DIP
  2. وارونگی کنترل (Inversion of Controls) یا به اختصار IoC

Dependency Inversion Principle:

اصول شی گرایی

یکی از اصول شی گرایی است که توسط آقای رابرت مارتین معروف به عمو باب ابداع شد. اصل وارونگی وابستگی در واقع یک اصل طراحی نرم افزار است که به ما در تولید یک نرم افزار با استحکام ارتباطی کم (Loosely Coupled) کمک می کند. به بیان ساده تر یعنی: ماژول های سطح بالا نباید به ماژول های سطح پایین وابسته باشند، بلکه باید هر دو به یک رابط وابسته شوند. انتزاع‌ (abstraction) نیز نباید به جزئیات وابسته باشد بلکه جزئیات باید به انتزاع وابسته باشند. (منظور از انتزاع دید کلی نسبت به یک شی است مثلا وقتی ما می‌گوییم میز ،چیزی که در ذهن ما نقش می‌بندد یک شکل کلی است ولی وقتی می‌گوییم میز ناهارخوری دقیقا مشخص می‌کنیم که چه نوع میزی است.)

Inversion of Control:

همانطور که ملاحظه کردید اصل وارونگی وابستگی به ما می‌گوید که وابستگی دو ماژول باید چگونه باشد. برای اجرای این موضوع باید از IoC یا از وارونگی کنترل استفاده کنیم. IoC روشی کاملا کاربردی‌ است که توسط آن ماژول‌های سطح بالا را به جای وابسته کردن به ماژول‌های سطح پایین، به انتزاع‌ها (abstractions) متصل می‌کند.

بگذارید با بیان یه مثال این مطلب را برای شما بیان کنیم. فرض کنید که سوار بر خودرو به سمت محل کار خود در حال رانندگی هستید، این یعنی شما در حال کنترل خودروی خود هستید. حالا اصل IoC چی میگه؟ این اصل،  وارونه کردن کنترل را پیشنهاد میدهد یعنی شما به جای آنکه خودتان رانندگی کنید، یک تاکسی بگیرید و بگذارید فرد دیگری رانندگی کند. در این صورت  کنترل از شما به راننده ی تاکسی وارونه می شود و شما دیگر مجبور نیستید خودتان رانندگی کنید و برای آنکه بتوانید بر روی کار اصلی خود تمرکز کنید، این کار را به راننده ی تاکسی محول می کنید.

آموزش سی شارپ

تعریف dependency injection  در سی شارپ:


تزریق وابستگی یا Dependency Injection یک پترن و الگوی طراحی است که هدف اصلی آن حذف وابستگی‌ های موجود بین دو کلاس با استفاده از یک رابط (Interface) است.

تعریف dependency injectionدر تزریق وابستگی ها دو اصطلاح داریم.

  • loosely coupled: وجود کمترین وابستگی بین دو کلاس
  • tight coupled: وجود بیشترین وابستگی بین دو کلاس 

بنابراین باید برنامه و نرم‌افزار خود را طوری طراحی کنیم که تا حد ممکن استحکام بین دو کلاس ضعیف باشد. چون زمانی که دو کلاس وابستگی بسیار دارند یا به اصطلاح در هم چفت شده‌اند، انعطاف‌پذیری نرم‌افزار را به شدت پایین می‌آورند.

مثال:

حالا می خواهیم با یک مثال جذاب داستان تزریق وابستگی در سی شارپ را برایتان بگوییم. فرض کنید می خواهیم یک بازی به نام نینجا بنویسیم که در آن جنگجوهای شجاع، برای به دست آوردن شرافتشان، با دشمنان خود میجنگند اما قبل از هر چیزی باید برای جنگجوهای خود یک سلاح مناسب تهیه کنیم. یک شمشیر که نام آن را Sword می گذاریم و دست به کار می شویم: این کلاس یک متد hit (ضربه زدن) دارد و هروقت آنرا فراخوانی کنیم، ضربه زده خواهد شد و target یا همان هدفمان نصف میشود! خوب، این از سلاح.

class Sword 
{
    public void Hit(string target)
    {
        Console.WriteLine("Chopped {0} clean in half", target);
    }
}


حالا باید سامورایی بسازیم برای حمله به دشمن.  کلاس سامورایی ما باید یک متد حمله یا Attack داشته باشد که وقتی آنرا فراخوانی می کنیم سامورایی با شمشیرش، هدف را نصف کند.

class Samurai
{
    readonly Sword sword;
    public Samurai() 
    {
        this.sword = new Sword();
    }

    public void Attack(string target)
    {
        this.sword.Hit(target);
    }
}


 حالا کافی است که سامورایی را ساخته و بجنگیم!

class Program
{
    public static void Main() 
    {
        var warrior = new Samurai();
        warrior.Attack("the evildoers");
    }
}

در این کد، ما با evildoers میجنگیم و او را با شمشیر نصف میکنیم. اما فرض کنید بخواهیم سامورایی ما با سلاح دیگری به غیر از شمشیر بجنگد! مثلا با شوریکن تیغه برنده شبیه ستاره. در این صورت باید کلاس سامورایی را کلا تغییر دهیم چون در کلاس سامورایی فقط از کلاس شمشیر استفاده کرده ایم. پس هر بار که نینجای ما بخواهد با یک سلاح جدید بجنگد، باید کلاس سامورایی را تغییر دهیم. به این ترتیب Tightly Coupled رخ می دهد یعنی وابستگی کلاس سامورایی به کلاس شمشیر.

طبیعتا ما این نوع وابستگی ها را دوست نداریم. چون مجبورمان میکند کدمان را تغییر دهیم. برای از بین بردن این وابستگی ها، از interfaceها استفاده میکنیم. بیایید یک interface به نام سلاح(weapon) بسازیم:

interface IWeapon
{
    void Hit(string target);
}


حالا کلاس شمشیر، را به این interface متصل میکنیم یا اصطلاحا آنرا Implement میکنیم:

class Sword : IWeapon
{
    public void Hit(string target) 
    {
        Console.WriteLine("Chopped {0} clean in half", target);
    }
}


حالا سامورایی را طوری تغییر میدهیم که به جای یک شمشیر، از یک سلاح استفاده کند:

class Samurai
{
    readonly IWeapon weapon;
    public Samurai() 
    {
        this.weapon = new Sword();
    }

    public void Attack(string target) 
    {
        this.weapon.Hit(target);
    }
}


حالا سامورایی ما میتواند از سلاح های مختلفی استفاده کند. فقط یک جای کار میلنگد. ما هنوز هم از شمشیر، در کلاس سامورایی استفاده می کنیم:
 

 this.weapon = new Sword();


پس باید کلاس سامورایی را یک کمی بهتر کنیم. کافی است که سلاح مورد نظر را از طریق constructor به سامورایی بدهیم:

class Samurai
{
    readonly IWeapon weapon;
    public Samurai(IWeapon weapon) 
    {
        this.weapon = weapon;
    }

    public void Attack(string target) 
    {
        this.weapon.Hit(target);
    }
}


حالا کافی است که سلاح مورد نظرمان را از طریق constructor به سامورایی تزریق کنیم. قبل از این، اجازه بدهید یک سلاح جدید به غیر از شمشیر هم بسازیم:

class Shuriken : IWeapon
{
    public void Hit(string target)
    {
        Console.WriteLine("Pierced {0}'s armor", target);
    }
}


وقتشه تا یک ارتش سامورایی با سلاح های مختلف بسازیم و به evildoers حمله کنیم. حاضرید؟

class Program
{
    public static void Main() 
    {
        var warrior1 = new Samurai(new Shuriken());
        var warrior2 = new Samurai(new Sword());
        warrior1.Attack("the evildoers");
        warrior2.Attack("the evildoers");
    }
}

 

کلام آخر:

کلام آخرامیدواریم توانسته باشیم این مفهوم را به خوبی برای شما بیان کرده باشیم. اگر به دنبال یک منبع یادگیری خوب برای آموزش سی شارپ هستید، می توانید از دوره ای که برای شما عزیزان در سایت قرار داده شده استفاده کنید و این اطمینان را داشته باشید که تمامی مباحث با زبانی شیوا و کاربردی برای شما گفته شده است.


کلمات کلیدی :
سی شارپ