2015-08-24 4 views
0

Я использую Ninject для выполнения некоторых IoC в моем приложении ASP.NET MVC.instanciates класс, используя ninject ioc в .net

У меня есть интерфейс "IService.cs":

public interface IService 
{ 
    string method(); 
} 

Я соответствующая реализация "Service.cs":

public class Service 
{ 
    string method() 
    { 
     return "result"; 
    } 
} 

Я сделал привязку в другом классе heriting от NinjectModule :

public class MyNinjectModule : NinjectModule 
{ 
    public override void Load() 
    { 
     RegisterServices(); 
    } 

    private void RegisterServices() 
    { 
     Kernel.Bind<IService>().To<Service>(); 
    } 

} 

у меня есть класс A, которые используют эту услугу:

public class A 
{ 
    private readonly IService _service; 
    private int i; 

    public A(IService service, int i) 
    { 
     this._service=service; 
     this.i=i; 
    }   

} 

Проблема в том, что теперь я не знаю, как создать экземпляр класса A в моем приложении. Это где я застрял, как я могу назвать Ninject сказать мое приложение, чтобы пойти получить реализацию моего интерфейса:

var myClass=new A(????) 
+0

Я предполагаю, что это на самом деле его '.Для ()' (не 'To ()') –

+0

Да извините, я исправить это – user2443476

+0

Его просто 'вар MyClass = новый A()' - '_service' будет конкретным классом –

ответ

1

Основная проблема заключается в том, что ваш Service класс не реализует IService.

public class Service 
{ 
    string method() 
    { 
     return "result"; 
    } 
} 

Это должно быть

public class Service : IService 
{ 
    public string method() 
    { 
     return "result"; 
    } 
} 

Но для экземпляра класса, лучший подход заключается в использовании composition root для построения графа объектов. В MVC это лучше всего реализовать путем реализации IControllerFactory.

public class NinjectControllerFactory : DefaultControllerFactory 
{ 
    private readonly IKernel kernel; 

    public NinjectControllerFactory(IKernel kernel) 
    { 
     this.kernel = kernel; 
    } 

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) 
    { 
     return controllerType == null 
        ? null 
        : (IController)this.kernel.Get(controllerType); 
    } 
} 

Использование

using System; 
using Ninject; 
using DI; 
using DI.Ninject; 
using DI.Ninject.Modules; 

internal class CompositionRoot 
{ 
    public static void Compose() 
    { 
     // Create the DI container 
     var container = new StandardKernel(); 

     // Setup configuration of DI 
     container.Load(new MyNinjectModule()); 

     // Register our ControllerFactory with MVC 
     ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(container)); 
    } 
} 

В Application_Start добавить:

CompositionRoot.Compose(); 

Вам также необходимо создать интерфейс для класса A и зарегистрировать его. Целое число не может быть разрешено автоматически, вы должны сделать это явно.

Kernel.Bind<IClassA>().To<A>() 
    .WithConstructorArgument("i", 12345); 

И тогда вы добавите свою зависимость к контроллеру. Зависимости зависимостей разрешаются автоматически.

public class HomeController : Controller 
{ 
    private readonly IClassA classA; 

    public HomeController(IClassA classA) 
    { 
     if (classA == null) 
      throw new ArgumentNullException("classA"); 

     this.classA = classA; 
    } 

    public ActionResult Index() 
    { 
     // Use this.classA here... 
     // IService will be automatically injected to it. 

     ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application."; 

     return View(); 
    } 
} 
Смежные вопросы