我有一个控制器,我想在构造函数中使用Dependency Injection,这是我的代码
private readonly IHomeService _iHomeService;
public HomeController(IHomeService iHomeService)
{
_iHomeService = iHomeService;
}
public HomeController()
{
}
当我删除没有任何参数的构造函数(第二个构造函数)时,我看到了这个错误:
No parameterless constructor defined
当我使用没有任何参数的构造函数时,我看到我的私有字段为空(_iHomeService = null),因为程序使用没有参数的构造函数。
如何为依赖注入解决此问题?
答案 0 :(得分: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>();
}
}
框架将控制控制器实例创建并传递约束器参数
答案 1 :(得分: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);
您还可以使用Ninject或StructureMap。
答案 2 :(得分:0)
听起来您希望自动将HomeService
类实例化并注入Controller。
使用像Ninject或StructureMap这样的IoC框架就可以为你做到这一点 - 一旦你进行了设置。
如果您不想使用IoC框架,则需要在构造函数中手动实例化HomeService
。