将构造函数参数添加到Ninject绑定

问题描述 投票:1回答:2

我有一个ASP.MVC项目,我正在使用ninject作为IOC容器。我已将绑定添加为基础结构文件夹中的单独类,如下所示:

public class NinjectControllerFactory : DefaultControllerFactory{

  private readonly IKernel _ninjectKernal;

  public NinjectControllerFactory()
  {
    _ninjectKernal = new StandardKernel();

    PSCCheckContext m = _ninjectKernal.Get<PSCCheckContext>(new IParameter[] 
        { new ConstructorArgument("appNamekey", "Name of Staff Application"), 
            new ConstructorArgument("serverLocationNameKey", "Location of Application Server") });

    AddBindings();
  }

所以你可以看到我试图在PSCCheckContext的构造函数中从web.config设置两个参数。这是另一个处理数据库访问的C#应用​​程序。 AddBindings()类只是将接口类映射到您期望的具体实现:

private void AddBindings()
{
  ...
  _ninjectKernal.Bind<IPSCCheckContext>().To<PSCCheckContext>();
}

我遇到的问题是PSCCheckContext类中有2个构造函数,第二个构造函数采用不同的参数:

public class PSCCheckContext : IPSCCheckContext
{
  public PSCCheckContext(string appNamekey, string serverLocationNameKey);
  public PSCCheckContext(string imgNamekey, string imgFlagKey, string serverLocationKeyName);

当我尝试击中Ninject注入此绑定的控制器时,我得到一个错误:

激活字符串时出错没有匹配的绑定可用,并且该类型不可自绑定。

激活路径: 3)将依赖字符串注入到PSCCheckContext类型的构造函数的参数imgNamekey中 2)将依赖关系IPSCCheckContext注入到AccountController类型的构造函数的参数pscCheckContext中 1)请求AccountController

建议: 1)确保已为字符串定义了绑定。 2)如果在模块中定义了绑定,请确保已将模块加载到内核中。 3)确保您没有意外创建多个内核。 4)如果使用构造函数参数,请确保参数名称与构造函数参数名称匹配。 5)如果使用自动模块加载,请确保搜索路径和过滤器正确无误。

即使我改变绑定更好(阅读http://thebrainyprofessionals.com/2013/05/20/passing-constructor-parameters-in-ninject/

IParameter appNamekey = new ConstructorArgument("appNamekey", "Name of Staff Application");
IParameter serverLocationNameKey = new ConstructorArgument("serverLocationNameKey", "Location of Application Server");
_ninjectKernal.Bind<IPSCCheckContext>().To<PSCCheckContext>()
  .WithConstructorArgument(appNamekey)
  .WithConstructorArgument(serverLocationNameKey);

我仍然得到同样的错误。我读过各种SO问题:

Inject value into injected dependency

Creating an instance using Ninject with additional parameters in the constructor

Convention based binding of constructor string arguments with Ninject

但似乎没有人遇到我的问题。

我究竟做错了什么?

我无法删除其他构造函数,因为它在不同的应用程序中,我认为它正被另一个系统使用。

这是完整性的AccountController构造函数

public class AccountController : BaseController

  private readonly IPSCCheckContext _pscCheckContext;

  public AccountController(IPSCCheckContext pscCheckContext)
  {
    this._pscCheckContext = pscCheckContext;
c# dependency-injection ninject ioc-container
2个回答
2
投票

您问题中的代码已被破坏。看到:

public NinjectControllerFactory()
{
    _ninjectKernal = new StandardKernel();

    PSCCheckContext m = _ninjectKernal.Get<PSCCheckContext>(new IParameter[] 
        { new ConstructorArgument("appNamekey", "Name of Staff Application"), 
            new ConstructorArgument("serverLocationNameKey", "Location of Application Server") });

    AddBindings();
}

特别:

PSCCheckContext m = _ninjectKernal.Get<PSCCheckContext>(new IParameter[] 
    { new ConstructorArgument("appNamekey", "Name of Staff Application"), 
        new ConstructorArgument("serverLocationNameKey", "Location of Application Server") });

这应该是做什么的?它实际上做的是让ninject instanciate一个PSCheckContext实例然后它忘记了它。除非PSCCheckContext的ctor对系统有副作用(这不是一个好的编程实践),否则这段代码没有任何影响(除了消耗CPU时间和内存)(=>注意PSCCheckContext m是一个局部变量,所以以后不能重复使用)。

我想你的意思是:

public NinjectControllerFactory()
{
    _ninjectKernal = new StandardKernel();

    _ninjectKernal.Bind<IPSCCheckContext>().To<PSCCheckContext>()
        .WithConstructorArgument("appNamekey", "Name of Staff Application")
        .WithConstructorArgument("serverLocationNameKey", "Location of Application Server");

    AddBindings();
}

这将IPSCCheckContext与构造函数参数绑定在一起,因此从现在起它应该可以注入到控制器中。


0
投票

你也可以试试这个:

kernel.Bind<IPSCCheckContext>().ToConstructor(ctorArg => new PSCCheckContext(
    "Name of Staff Application", 
    "Location of Application Server"));

我比WithConstructorArgument更喜欢这个,因为如果你改变arg名称,你的DI绑定不会破坏。

© www.soinside.com 2019 - 2024. All rights reserved.