کار با Ninject

کار با Ninject

بسم الله الرحمن الرحیم

آموزش dependency injection

بسم الله الرحمن الرحیم

آموزش dependency injection

این مطلب را برای تیم طراحی قرار دادم انشالله دوستان این تیم از آن استفاده نمایند.

چرا Ninject مفید است؟
بخش اعظمی از دست آوردهای به وجود آمده در حوزه نرم افزار از نسخه ابتدایی منتشر شده بدست می آید.
بیشتر زمان سرمایه گذاری شده در بخش تحلیل بعد از شروع به کار نرم افزار هزینه می شود.
باعث می شود تغییرات نرم افزار شما بسیار ساده تر انجام شود.

بعد از استفاده spring.net به مدت طولانی در asp.net به دنبال یک روش ساده تر و سریعتر و نه روشی بر پایه تریق وابستگی به صورت xml  بودم. برای برنامه های MVC4 در نهایت به Ninject رسیدم چون رویکرد آن XML ای نیست و ساده است و استفاده از آن راحت است.

چطور تزریق کننده وابستگی را انتخاب کنیم؟
هر تزریق کننده مزایا و معایب خود را دارد و یک سری ویژگی را با خود به همراه دارد.
انتخاب یک تزریق کننده بستگی به مواردی دارد که شما بیشتر نیاز دارید دارد و این موضوع کاملا قابل بررسی است.

Ninject یک تزریق کننده متن باز است که برای NET. به وسیله Nate Kohari تولید شده است و یک سری ابزار مناسب به همراه دارد که همچنین ابزارهایی نیز برای MVC3 در آن قرارداده شده است. به هرحال، اگر شما هم مثل من به دنبال راه جدید هستید Ninject را دوست خواهید داشت.

چرا تزریق وابستگی؟

چند مورد از مزایای تزریق وابستگی بجای اینکه از لحاظ ماهیتی خود کلاس وابستگی  داشته باشد به صورت زیر لیست شده اند:

  • وابستگی تحمیل شده را کاهش می دهد، ایجاد انعطاف در پیاده سازی جایگزین برای یک سرویس مشخص بدون نیاز به کامپایل مجدد
  • اتصال سست بین کلاس ها با استفاده کردن از interface
  • کدها قابلیت استفاده مجدد، قابلیت تست، قابلیت خواندن، بیشتر پیدا می کنند

اضافه کردن Ninject

ninject را به پروژه اضافه کنید و سپس به دنبال آن فایل های زیر را نیز باید اضافه شود:

  1. Ninject.dll
  2. Ninject.Web.Common.dll
  3. Ninject.Web.Mvc.dll


کد کنترلر را با تعریف یک متغییر read-only برای سرویس خودتان و تابع سازنده را با معرفی کردن پارامتر سرویس نمونه (منظورم instance است) مانند زیر تغییر دهید:

namespace NinjectMvc4.Controllers
{
     public class HomeController : Controller
     {
        private readonly IMessageService _messageService;
         public HomeController(IMessageService  messageService)
         {
             _messageService = messageService;
         }

         public ActionResult Index()
       {
           ViewBag.Message = _messageService.GetWelcomeMessage();
            return View();
       }

    }
}


در اینجا ما یک اینترفیس با نام  IMesssageService داریم و می خواهیم messageService_  را در MessageService به وسیله Ninject تزریق کنیم.

namespace NinjectMvc4.ServiceLayer
{
    public class MessageService:IMessageService
    {
        public string GetWelcomeMessage()
        {
            return "Welcome to Ninject MVC4 Example";
        }
    }
}



تغییرات فایل Global.asax:

کلاس MvcApplication از کلاس انتزاعی NinjectHttpApplication  ارث می برد که این کلاس قسمتی از فضای نامی Ninject.Web.Common است.
متد CreateKernel را به صورت زیر پیاده سازی می کنیم.
یک شی از StandardKernel ایجاد می کنیم، بارگذاری اسمبلی های قابل اجرا در kernel را انجام می دهد. ارتباط بین Interface سرویس و پیاده سازی تزریق شده:

در این مثال، درحالی که کنترلری را با تزریق نمونه ای از MessageService درون سازنده HomeController می سازید، می توان آن را به متغیر messageService_ تخصیص داد.
 




namespace NinjectMvc4
{
    public class MvcApplication : NinjectHttpApplication
    {
        protected override IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            kernel.Load(Assembly.GetExecutingAssembly());
            kernel.Bind().To();
            return kernel;
        }
        protected override void OnApplicationStarted()
         {
             base.OnApplicationStarted();
             AreaRegistration.RegisterAllAreas();
             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
             RouteConfig.RegisterRoutes(RouteTable.Routes);
             BundleConfig.RegisterBundles(BundleTable.Bundles);
         }
     }
 }



متد OnApplicationStarted را برای ثبت Filters, routes ,bundles در پروژه Override می کنیم. MVC4 به صورت استاندارد از Application_Start در زمانی که از Ninject استفاده نمی شود، استفاده می کند.
کار تمام شد، حال نرم افزار را اجرا می کنیم و پیغامی را که نوشته ایم را از MessageService که به HomeController تزریق کرده ایم دریافت می کنیم.



Ninject با MVC4 ادغام شده اما تفاوتی ندارد حتی اگر MVC3 هم استفاده کنید.
اگر می خواهید در asp.net webapi از تزریق وابستگی استفاده کنید باید از DependencyResolver استفاده کنید می بایست:
System.Web.Http.Dependencies.IDependencyResolver این را پیاده سازی کنید.

چرا؟ زیرا Ninject’s Dependency Resolver جاری با پیاده سازی System.Web.Mvc.IDependencyResolver نمی توان به GlobalConfiguration.Configuration از برنامه WebApi اختصاص داد، این انتظارات یک نمونه از System.Web.Http.Dependencies.IDependencyResolver  بجای System.Web.Mvc.IDependencyResolver  است

 
public class LocalNinjectDependencyResolver : 
     System.Web.Http.Dependencies.IDependencyResolver
    {
         private readonly IKernel _kernel;

         public LocalNinjectDependencyResolver(IKernel kernel)
         {
             _kernel = kernel;
         }
         public System.Web.Http.Dependencies.IDependencyScope BeginScope()
         {
             return this;
         }

         public object GetService(Type serviceType)
         {
             return _kernel.TryGet(serviceType);
         }

         public IEnumerable< object > GetServices(Type serviceType)
         {
             try
             {
                 return _kernel.GetAll(serviceType);
             }
             catch (Exception)
             {
                 return new List< object >();
             }
         }

         public void Dispose()
         {
             // When BeginScope returns 'this', the Dispose method must be a no-op.
         }
    }


متد CreateKernel را مانند زیر برای اختصاص دادن یک نمونه از  LocalNinjectDependencyResolver به GlobalConfiguration تغییر می دهیم :

protected override IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            kernel.Load(Assembly.GetExecutingAssembly());
            GlobalConfiguration.Configuration.DependencyResolver = new LocalNinjectDependencyResolver(kernel); 
            return kernel;
        }


نظرات

  • Hannah Martinez
    رهگذر
    دو شنبه 11 دی 1278 - 0:00

    سلام.

    معذرت می خوام در اینجا و پیش یک استاد حرف می زنم.
    اما تو مقایسه هایی که از نظر سرعت و کارایی میشه هر کدوم خوبی خودشون رو دارن .
    در بعضی موارد ninject و بعضی موارد stracture.
    اما نمی شه برتری خواص به هیچ کدوم داد.
    ولی نینجکت کاربردهای زیادی داره البته در بقه هم هست اما در آموزش های لیندا از اون برای ساخت افزونه ها هم استفاده شده.
    موفق باشد

  • Hannah Martinez
    فخاری
    دو شنبه 11 دی 1278 - 0:00

    سلام
    به نظرتون استفاده از StructureMap بهتر است یا Ninject ؟

    • Judith Bell
      پاسخ
      اسماعیلشیدایی
      دو شنبه 11 دی 1278 - 0:00

      با عرض سلام

      پاسخ به سوال شما خیلی مشکل است، زیرا تعریف خوب و بد، در شرایط و موقعیت های متفاوت ممکن است تغییر کند، شما باید ببیند از ابزارتان چه انتظاراتی دارید.

      یاعلی

نظرات یا سوالات خودرا با ما درمیان بگذارید

0912 097 5516 :شماره تماس
0713 625 1757 :شماره تماس