0

我有一個控制器和我想要使用依賴注入與構造,這是我的代碼依賴注入構造衝突

private readonly IHomeService _iHomeService; 

    public HomeController(IHomeService iHomeService) 
    { 
     _iHomeService = iHomeService; 
    } 

    public HomeController() 
    { 

    } 

當我刪除構造不帶任何參數(第二個構造函數),我看到這個錯誤:

No parameterless constructor defined 

,當我使用構造不帶任何參數,我看到我的私有字段爲空(_iHomeService = NULL),因爲程序使用的構造函數沒有參數。

如何解決依賴注入的這個問題?

+0

您是否在使用Castle Windsor這樣的IoC容器? –

+0

不,我不使用任何Ioc容器 –

回答

1

那麼,要做依賴注入你需要使用框架或使用控制器工廠。

嘗試ninject

public class HomeController : Controller 
{ 
    private readonly IWelcomeMessageService welcomeMessageService; 

    public HomeController(IWelcomeMessageService welcomeMessageService) 
    { 
     this.welcomeMessageService = welcomeMessageService; 
    } 

    public void Index() 
    { 
     ViewModel.Message = this.welcomeMessageService.TodaysWelcomeMessage; 
     return View(); 
    } 
} 

public class WelcomeMessageServiceModule : NinjectModule 
{ 
    public override void Load() 
    { 
     this.Bind<IWelcomeMessageService>().To<WelcomeMessageService>(); 
    } 
} 

該框架將在控制器實例創建控制和傳遞constractor PARAMS

+0

您實際上不需要一個框架來執行DI,因此可以手動注入依賴關係。 –

+0

@JoeR - 正確,nin​​ject是一個選項... –

+0

Ninject是一個框架 - 你不必使用任何... –

0

ASP.NET使用ControllerFactory實例點播你的控制器。這個類需要你的控制器有一個無參數的構造函數,它可以用來創建它的一個實例。

您需要使用依賴注入框架來創建控制器並注入所需的依賴關係。 ASP.NET has some dependency injection capability,但我知道它是有缺陷的。我建議使用Castle Windsor來管理你的依賴注入。它與ASP.NET集成得非常好,並且有一個關於集成它的教程here

如果你沿着這條路走下去,你最終與你的控制器和服務的安裝程序:

public class Installer : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     container.Register(Classes.FromThisAssembly().BasedOn<IController>().LifestyleTransient()); 
     container.Register(Component.For<IHomeService>.ImplementedBy<HomeService>()); 
    } 
} 

..和新ControllerFactory來創建它們:

public class WindsorControllerFactory : DefaultControllerFactory 
{ 
    private readonly IKernel _kernel; 

    public WindsorControllerFactory(IKernel kernel) 
    { 
     _kernel = kernel; 
    } 

    public override void ReleaseController(IController controller) 
    { 
     _kernel.ReleaseComponent(controller); 
    } 

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) 
    { 
     if (controllerType == null) 
     { 
      throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path)); 
     } 
     return (IController) _kernel.Resolve(controllerType); 
    } 
} 

最後,您將創建一個容器並設置一個新的控制器工廠:

var container = new WindsorContainer().Install(new Installer()); 
var controllerFactory = new WindsorControllerFactory(_container.Kernel); 
ControllerBuilder.Current.SetControllerFactory(controllerFactory); 

您也可以使用NinjectStructureMap

0

這聽起來像你期待,自動的HomeService類實例化和注入控制器。

使用像Ninject或StructureMap IoC框架會爲你做的 - 一旦你設置它。

如果你不想使用IoC框架,你需要手動實例HomeService在構造函數。