در توسینسو تدریس کنید

و

با دانش خود درآمد کسب کنید

آموزش برنامه نویسی شی گرا در (#C) قسمت 13: Dependency Injection

در قسمت قبلی سری آموزشی با مفهوم interface ها آشنا شدیم. interface ها نقش بسیار موثری در روند نوشتن یک برنامه بازی می کنند و در صورتی که یک برنامه نویس با نحوه استفاده صحیح از interface ها آشنا باشه، توانایی ایجاد کدهایی ساختاریافته و قابل گستری و نگهداری رو داره. در این قسمت از سری آموزشی زبان برنامه نویسی سی شارپ و برنامه نویسی شئ گرا، با دو مفهوم بسیار مهم در برنامه نویسی آشنا خواهیم شد، IoC که مخفف Inversion of Control و DI که مخفف Dependency Injection هست.همه ما در طول زندگی با وسایل زیادی سر و کار داریم، از وسایل اولیه زندگی مانند ماشین، یخچال، تلویزیون و ... تا وسایل که هر کس بر اساس نیاز کاری خودش با اونها سر و کار داره، مانند کامپیوتر یا لپ تاپ و گوشی. برای مثال، گوشی هوشمند خود را فرض کنید، این گوشی از قطعات زیادی تشکیل شده، صفحه نمایش، پردازنده، حافظه رم، باتری و کلی قطعات دیگه. حالا اتفاقی پیش میاد و خدای نکرده گوشی شما از دستتون میافته و صفحه نمایش گوشیتون آسیب میبینه.

کاری که می کنید باید گوشی رو به یک نمایندگی برده و صفحه نمایش رو تغییر بدید. حالا فرض کنید که گوشی شما جوری طراحی شده باشه که با آسیب دیدن صفحه نمایش نیاز باشه تا یک گوشی جدید تهیه کنید!!!! یا برای کارتون یک لپ تاپ تهیه کردید. بعد از مدتی نیاز دارید تا حافظه رم لپ تاپ رو افزایش بدید. در این حالت شما لپ تاپ رو پیش نمایندگی یا یک کارشناس در این زمینه می برید و حافظه رم لپ تاپ شما افزایش داده میشه. حال فرض کنید که لپ تاپ شما همچین قابلیتی نداشته باشه و شما نیاز باشه برای تغییر یا ارتقا حافظه یک لپ تاپ جدید خریداری کنید! برای حل این مشکل لوازم الکتریکی از قطعات مختلفی تشکیل شدند که قابلیت تغییر یا تعویض دارند. به این قابلیت طراحی ماژولار گفته میشه. در پیاده سازی سیستم های نرم افزاری نیز شما نیز به عنوان برنامه نویس باید با همچین دیدی نسبت به پیاده سازی نرم افزار اقدام کنید. ما در اینجا در مورد تغییر یکی از قسمت های نرم افزار صحبت خواهیم کرد که ارتباط مستقیمی به interface ها و IoC و DI دارد.برای آشنایی بیشتر با این مفاهیم، با یک مثال جلو میرویم. فرض کنید سیستمی پیاده سازی کردید که اعضاء می توانند در این سامانه اقدام به ثبت نام کنند. برای عملیات های مرتبط با مدیریت اعضاء کلاسی با نام Members می نویسیم:

public class Members
{
    public void Register(string firstName, string lastName)
    {
        // add member to database            
    }
}

همانطور که مشاهده می کنید این کلاس یک متد با نام Register دارد که عملیات ثبت نام اعضاء را انجام می دهد (تنها متد تعریف شده و کدی برای ثبت نام نوشته نشده است). پس از مدتی، فردی که درخواست پیاده سازی نرم افزار را از شما داشته، می خواهد زمانی که یک عضو جدید به سامانه اضافه شد، یک ایمیل برای شخص ارسال شود. کد کلاس به صورت زیر تغییر می کند:

public class Members
{
    public void Register(string firstName, string lastName)
    {
        // add member to database
        // send email to name@host.com
    }
}

تا اینجا مشکلی نیست، بعد از مدتی مجدداً شخص ذکر شده از شما می خواهد به جای ارسال ایمیل، یک پیامک برای او ارسال شود. شما مجدداً باید کد داخل متد Register را تغییر داده و عملیات ارسال پیامک را اضافه کنید:

public class Members
{
    public void Register(string firstName, string lastName)
    {
        // add member to database
        // send sms to 0912*******
    }
}

با هر درخواست، ما دائماً در حال تغییر کدهای نوشته شده داخل کلاس Members هستیم. اگر کمی اصولی کار کنیم، کلاسی با نام SmsManager ایجاد می کنیم و از آن کلاس داخل کلاس Members استفاده می کنیم:

public class SmsManager
{
    public void Send(string message)
    {
        // send sms to 0912*******
    }
}

public class Members
{
    public void Register(string firstName, string lastName)
    {
        // add member to database
        var sms = new SmsManager();
        sms.Send("New user registered!");
    }
}

حالا فرض کنید که مجدد، شخص ذکر شده درخواست جایگزینی ارسال ایمیل به جای پیامک را به ما می دهد، ما کلاسی با نام EmailManager تعریف کرده و از آن استفاده می کنیم:

public class EmailManager
{
    public void Send(string message)
    {
        // send message to name@host.com
    }
}

public class SmsManager
{
    public void Send(string message)
    {
        // send sms to 0912*******
    }
}

public class Members
{
    public void Register(string firstName, string lastName)
    {
        // add member to database
        var email = new EmailManager();
        email.Send("New user registered!");
    }
}

با تعریف کلاس های EmailManager و SmsManager، حجم تغییرات کلاس Members خیلی کم شد. اما می توان این تغییرات را خیلی کمتر کرد. در اینجا می خواهیم یکی از کاربردهای بسیار مهم interface ها، یعنی IoC یا Inversion of Control را بررسی کنیم. در ابتدا ما یک interface با نام INotifySender به صورت زیر ایجاد می کنیم:

public interface INotifySender
{
    void Send(string message);
}

اگر دقت کنید، متد signature متد Send در کلاس های EmailManager و SmsManager مشترک است. پس این دو کلاس قابلیت پیاده سازی INotifySender را دارند. کلاس های ذکر شده را به صورت زیر تغییر می دهیم:

public class EmailManager : INotifySender
{
    public void Send(string message)
    {
        // send message to name@host.com
    }
}

public class SmsManager : INotifySender
{
    public void Send(string message)
    {
        // send sms to 0912*******
    }
}

در قدم بعدی باید کلاس Members را جوری تغییر دهیم تا وابستگی متد Register به یک کلاس خاص از بین برود، یعنی به کلاس EmailManager یا SmsManager وابسته نباشد. اینکار را می توان با استفاده از INotifySender انجام داد. کد کلاس Members را به صورت زیر تغییر می دهیم:

public class Members
{
    private readonly INotifySender sender;

    public Members()
    {
        sender = new EmailManager();
    }

    public void Register(string firstName, string lastName)
    {
        // add member to database
        sender.Send("New member registered!");
    }
}

تغییرات کد بالا را با هم بررسی می کنیم، فیلدی تعریف کردیم از نوع INotifySender که داخل متد Register از این فیلد برای ارسال پیام استفاده می کنیم. این فیلد از داخل سازنده کلاس Members مقدار دهی می شود. در کد بالا ما شئ ای از نوع EmailManager که INotifySender را پیاده سازی کرده است ایجاد کرده و داخل فیلد sender میریزیم. حال فرض کنید که بخواهیم عملیات را از ایمیل به پیامک تغییر دهیم، برای اینکار تنها سازنده را به صورت زیر تغییر می دهیم:

public class Members
{
    private readonly INotifySender sender;

    public Members()
    {
        sender = new SmsManager();
    }

    public void Register(string firstName, string lastName)
    {
        // add member to database
        sender.Send("New member registered!");
    }
}

به عملیات بالا، Inversion of Control گفته می شود. ما در حقیقت وابستگی متد Register را به یک کلاس خاص از بین بردیم. به این نوع پیاده سازی tightly coupled گفته می شود. اما باز یک مشکل وجود دارد، ما هنوز هم در حال تغییر کلاس Members هستیم. در قدم بعد باید وابستگی کلاس Members را به کلاس های EmailManager و SmsManager به طور کامل از بین ببریم. برای اینکار، ما به جای ساختن شئ داخل سازنده، آن را به عنوان یک پارامتر به سازنده کلاس Members ارسال می کنیم:

public class Members
{
    private readonly INotifySender sender;

    public Members(INotifySender sender)
    {
        this.sender = sender;
    }

    public void Register(string firstName, string lastName)
    {
        // add member to database
        sender.Send("New member registered!");
    }
}

نحوه استفاده از کلاس Members به صورت زیر است:

var members = new Members(new EmailManager());
members.Register("Hossein", "Ahmadi");

حال اگر بخواهیم نوع ارسال پیام را به پیامک تغییر دهیم تنها کافیست نوع شئ ارسالی به سازنده کلاس Members را تغییر دهیم:

var members = new Members(new SmsManager());
members.Register("Hossein", "Ahmadi");

به این تکنیک، DI یا Dependency Injection گفته می شود. ترکیب IoC و DI کمک زیادی به شما در نوشتن کدهایی می کنند که به راحتی قابلیت تغییر و به روز رسانی دارند. در این مقاله با یکی از کاربردهای بسیار مهم interface ها آشنا شدید. کتابخانه های آماده ای برای IoC و DI وجود دارند که به آنها IoC Container نیز گفته می شوند که روند DI رو برای شما به عنوان یک برنامه نویس بسیار راحت تر می کنند. در یک فیلم آموزشی در مورد IoC Container ها به تفصیل صحبت خواهیم کرد. در قسمت بعدی با مفهوم Type Casting و انواع Cast ها در زبان سی شارپ آشنا خواهیم شد. ITPRO باشید

نویسنده : حسین احمدی
منبع : جزیره برنامه نویسی وب سایت توسینسو
هرگونه نشر و کپی برداری بدون ذکر منبع و نام نویسنده دارای اشکال اخلاقی است
#interface_ها_در_سی_شارپ #آموزش_زبان_سی_شارپ #آموزش_گام_به_گام_برنامه_نویسی_سی_شارپ #آموزش_برنامه_نویسی_شئ_گرا #برنامه_نویسی_شئ_گرا_چیست؟ #آموزش_dependency_injection #آموزش_برنامه_نویسی #inversion_of_control_چیست؟ #dependency_injection_چیست؟
عنوان
1 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 1 : مقدمه رایگان
2 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 2 : کلاس، اشیاء رایگان
3 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 3 : فیلد و رفتار رایگان
4 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 4 : Property ها رایگان
5 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 5 : ایجاد اشیاء رایگان
6 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 6 : وراثت رایگان
7 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 7 : Polymorphism رایگان
8 آموزش برنامه نویسی شی گرا در (#C) قسمت 8 : abstract و sealed رایگان
9 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 9:سازنده در وراثت رایگان
10 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 10 : متد Extension رایگان
11 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 11: Value ها رایگان
12 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 12 : Interface رایگان
13 آموزش برنامه نویسی شی گرا در (#C) قسمت 13: Dependency Injection رایگان
14 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 14 : انواع Cast ها رایگان
15 آموزش برنامه نویسی شی گرا (#C) قسمت 15 : Operator Overloading رایگان
16 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 16 : Box و Unbox رایگان
17 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 17 : Generics رایگان
18 آموزش برنامه نویسی شی گرا در (#C) قسمت 18 : List و Dictionary رایگان
19 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 19 : مدیریت خطاها رایگان
زمان و قیمت کل 0″ 0
4 نظر
علیرضا موسوی

سلام

جناب مهندس اگر مشخص بکنید که آموزش ها رو در یک بازه ی زمانی مشخص منتشر کنید

بسیار عالی خواهد شد.

ممنون

--موفق باشید

علی  ورزشی

جناب احمدی یه سوال در مورد فریم ورک هایی هست که برای ِDI توسعه دادن

ببینید مثلا یکی از انواع همین DI ها واسه سازنده ها هست ... در واقع این جور که متوجه شدم بعد از یه مدت استفاده از سازنده ها با امضاهای متوافت و با ورودی های متفاوت ازاینترفیس های متفاوت تو برنامه زیاد میشه اگه اشتباه نکنم از Ninject برای این استفاده میشه که بیاد Di رو پیاده سازی کنه ... می خواستم ببینم این طور که بنده متوجه شدم درست هست که در واقع برای کنترل کردن این سازنده ها که بشه نظارت بهتری روش داشت در واقع این فریم ورک ها اومدن ساخته شدن یا این که از این مفاهیم به درستی تو پروزه ها استفاده نمیشده و اومدن در واقع یه نوع استاندارد سازی کردن ؟

با تشکر از شما

aakawmg1

سلام چرا اجرای این روش چیزی رو در خروجی نشون نمی ده؟

DI

nabiloo.reza@gmail.com

عالی عالی عالییییی ...... با اینکه توو متن توضیح میدین ولی آموزشون کاملا شیواست. آدم کیف میکنه....

بی نهایت سپاسگزارم

نظر شما
برای ارسال نظر باید وارد شوید.
از سرتاسر توسینسو
تنظیمات حریم خصوصی
تائید صرفنظر
×

تو می تونی بهترین نتیجه رو تضمینی با بهترین های ایران بدست بیاری ، پس مقایسه کن و بعد خرید کن : فقط توی جشنواره پاییزه می تونی امروز ارزونتر از فردا خرید کنی ....