تزریق وابستگی با استفاده از Microsoft Unity

سه شنبه 4 اسفند 1394

زمانی که نرم افزار یا اپلیکیشنی را توسعه می دهیم از الگوهای طراحی یا Design Pattern های مشخصی پیروی می کنیم. این الگوهای طراحی کاربردهای متعدد دارند؛ توسعه دهندگان عمدتا آن ها را برای نوشتن کد بهتر استفاده کرده و از طریق آنها اپلیکیشن هایی ایجاد میشود که برای تست، اشکال زدایی، نگهداری و گسترش اپلیکیشن کارآمد تر هستند. در این مقاله می خواهیم ایجاد تزریق وابستگی ها را با استفاده از Microsoft Unity توضیح دهیم.

تزریق وابستگی با استفاده از Microsoft Unity

در حال حاضر برای تولید اپلیکیشن عمدتا از الگوی طراحی S.O.L.I.D استفاده می کنیم. S.O.L.I.D یک عبارت مخفف برای پنج اصل اول طراحی شی گرا می باشد که توسط Robert C. Martin ارائه شده است. این اصول اولیه زمانی که با یکدیگر ترکیب می شوند، توسعه و نگهداری اپلیکیشن را برای برنامه نویس آسان تر می سازند.

نام S.O.L.I.D بسیار جالب است، در واقع  هر حرف از S.O.L.I.D یک اصل را نشان می دهد که برای توسعه نرم افزار بسیار مهم است. در اینجا معنی دقیق این اصول را به صورت زیر نشان می دهیم:

S: اصل Single-responsibility

O: اصل Open-closed

L: اصل Liskov substitution

I: اصل Interface segregation

D: اصل Dependency Inversion

در این مقاله قصد داریم  آخرین اصل ذکر شده را توضیح دهیم که Dependency Inversion می باشد:

Dependency Inversion

اگر در گوگل جستجو کنید معانی مختلفی را برای تعریف دقیق این مفهوم پیدا می کنید. اما یکی از آنها که در ویکی پدیا وجود دارد و مناسب است به صورت زیر می باشد:

"در برنامه نویسی شیئ گرا اصل وابستگی وارونگی یا Dependency Inversion  به یک شکل مشخص از ماژول های نرم افزاری جدا از هم اشاره می کند."

در اینجا دو مفهوم اصلی از Dependency Inversionوجود دارد که به صورت زیر می باشد:

1.  (Dependency Inversion Principle (DIP می گوید که ماژول ها یا کلاس های سطح بالا نباید به ماژول ها یا کلاس های سطح پایین وابسته باشد. هر دو باید بر اساس مفاهیم انتزاعی باشند.

2. انتزاع ها نباید به جزئیات بستگی داشته باشند. جزئیات نیز باید بر اساس مفاهیم انتزاعی باشند.

Dependency injection یک تکنیک برای توسعه نرم افزار به روش مستقل است. مستقل در sensethe یعنی، هیچ ماژولی توسعه نرم افزار به ماژول دیگر وابسته نباشد.

تکنیک Sothe dependency injection ، تمام وابستگی های ماژول های پایین تر را تزریق کرده و این وابستگی را برای ماژول های بالاتر بدون تماس مستقیم ایجاد می کند. ماژول ها یا کلاس های سطح بالا قوانین کسب و کار یا منطق را در یک اپلیکیشن پیاده سازی می کنند. ماژول های یا کلاس های سطح پایین با عملگرهای مختلف مواجه می شوند؛ به عبارت دیگر ممکن است آنها با نوشتن اطلاعات در پایگاه داده یا ارسال پیام ها به سیستم عامل و یا سرویس ها مواجه شوند.

این اپلیکیشن کاملا وابسته(fully dependent) چیزی شبیه به شکل زیر به نظر می رسد. تمام ماژول ها به صورت محکم با یکدیگر همراه شده اند.

برای هر Dependency Inversion چیزی بین آن ها وجود دارد که این ماژول ها را از هم جدا می کند.

 

در اینجا می خواهیم توضیح دهیم که چگونه می توان Dependency Inversion را در یک پروژه MVC پیاده سازی کرد.

تزریق وابستگی با استفاده از Microsoft Unity

1. یک پروژه جدید ایجاد کنید:

 

2. الگوی MVC را انتخاب کنید.

3. حالا یک کلاس با نام Employee.cs و یک اینترفیس با نام Iemployee.cs به صورتی که در زیر نشان داده شده ایجاد کنید.

 

4. حالا به Manage NuGet Package رفته و Unity.Mvc3 را نصب کنید.

بعد از نصب دو رفرنس در پروژه به صورت زیر دریافت می کنیم:

 

بعد از نصب unity ما این دو را در رفرنس ها دریافت می کنیم.

5. حالا وقتی پوشه App_start را چک کنیم خواهیم دید که یک فایل کلاس جدید از unity را با نام Bootstrapper.cs دریافت کرده ایم.

 در زیر کد Bootstrapper.cs را به صورت زیر داریم و اینترفیس را به شکل زیر ثبت کرده ایم:

private static IUnityContainer BuildUnityContainer()    
{    
    var container = new UnityContainer();    
    container.RegisterType<IEmployee,Employee>();    
  
    // register all your components with the container here    
    // it is NOT necessary to register your controllers    
        
    // e.g. container.RegisterType<ITestService, TestService>();                
  
    return container;    
}

در Unity Container نوعی از Iemployee را با کلاس Employee ثبت کرده ایم.

6. به global.ascx رفته و bootstrapper را به صورت زیر ثبت کنید:

public class MvcApplication : System.Web.HttpApplication    
    
   protected void Application_Start()    
   {    
       AreaRegistration.RegisterAllAreas();    
       FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);    
       RouteConfig.RegisterRoutes(RouteTable.Routes);    
       BundleConfig.RegisterBundles(BundleTable.Bundles);    
  
       Bootstrapper.Initialise();    
   }

7. حالا ما یک متد method در interface نوشته و اینترفیس را در این کلاس به صورت زیر پیاده سازی می کنیم. در اینجا ما یک متد ساده نوشته ایم:

public interface IEmployee  
{  
   string savedata();  
}

8. حالا در کلاس Employee یک اینترفیس را نوشته ایم و متد savedata را تعریف کرده ایم:

public class Employee:IEmployee    
{    
  
    public string savedata()    
    {    
        return "Data Saved...";    
    }    
} 

تا اینجا تقریبا کار ما به پایان رسیده است. حالا می بینیم که چگونه این موارد را از هم جدا می کنیم.

توجه: زمانی که ما یک شیئ از یک کلاس را ایجاد کرده و متد آن کلاس را با شیئ خود از کلاس دیگر فراخوانی می کنیم، می گوییم که این دو کلاس کاملا با هم همراه (coupled ) یا به یکدیگر وابسته(dependent) هستند.

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

9. در کنترلر Home فقط کد زیر را اضافه می کنیم:

public class HomeController : Controller    
{    
    IEmployee iemployee;    
    public HomeController(IEmployee _iemployee)    
    {    
        iemployee = _iemployee;    
  
    } 

بنابراین در اینجا  Constructor Injection را با ایجاد یک سازنده و ارسال وابستگی به سازنده ایجاد می کنیم.

حالا وقتی که شما تلاش می کنید به متد کلاس employee دسترسی داشته باشید می توانید آن را در یک action method دیگر انجام دهید.

 

کد مورد نظر در زیر وجود دارد.

public class HomeController : Controller    
{    
    IEmployee iemployee;    
    public HomeController(IEmployee _iemployee)    
    {    
        iemployee = _iemployee;    
  
    }    
    public ActionResult Index()    
    {    
       string result= iemployee.savedata();    
       return Content(result);    
    }

 

حالا برنامه را ذخیره و آن را اجرا کنید. با این کار خروجی زیر را نشان داده می شود:

 

بنابراین در این جا دیدیم که چگونه می توان dependency injection را با استفاده از Unity پیاده سازی کرد.

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید