0

我有一个控制器,我想将依赖注入与构造函数一起使用,这是我的代码

    private readonly IHomeService _iHomeService;

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

    public HomeController()
    {

    }

当我删除没有任何参数的构造函数(第二个构造函数)时,我看到了这个错误:

No parameterless constructor defined

当我使用没有任何参数的构造函数时,我看到我的私有字段为 null(_iHomeService = null),因为程序使用了没有参数的构造函数。

如何解决依赖注入的这个问题?

4

3 回答 3

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>();
    }
}

框架将控制控制器实例的创建并传递构造器参数

于 2013-10-30T09:23:26.283 回答
0

ASP.NET 使用 aControllerFactory按需实例化您的控制器。这个类要求你的控制器有一个无参数的构造函数,它可以用来创建它的一个实例。

您需要使用依赖注入框架来创建控制器并注入所需的依赖。ASP.NET 有一些依赖注入功能,但我知道它有缺陷。我建议使用Castle Windsor来管理您的依赖注入。它与 ASP.NET 集成得很好,这里有一个集成教程

如果你沿着这条路线走,你最终会得到一个控制器和服务的安装程序:

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

于 2013-10-30T09:27:31.413 回答
0

听起来您希望自动将HomeService类实例化并注入到 Controller 中。

使用 Ninject 或 StructureMap 之类的 IoC 框架将为您做到这一点 - 一旦您设置了它。

如果您不想使用 IoC 框架,则需要HomeService在构造函数中手动实例化 。

于 2013-10-30T09:28:40.403 回答