将构造函数参数添加到 Ninject 绑定
Add Constructor Arguments To Ninject Binding
我有一个 ASP.MVC 项目,我在其中使用 ninject 作为 IOC 容器。我已将绑定作为单独的 class 添加到 Infrastructure 文件夹中,如下所示:
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() class 只是将接口 classes 映射到您所期望的具体实现:
private void AddBindings()
{
...
_ninjectKernal.Bind<IPSCCheckContext>().To<PSCCheckContext>();
}
我遇到的问题是 PSCCheckContext class 中有 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
但是 none 似乎遇到了我的问题。
我做错了什么?
我无法删除额外的构造函数,因为它在不同的应用程序中,我认为它正被不同的系统使用。
这里是完整的 AccountController 构造函数
public class AccountController : BaseController
private readonly IPSCCheckContext _pscCheckContext;
public AccountController(IPSCCheckContext pscCheckContext)
{
this._pscCheckContext = pscCheckContext;
您问题中的代码已损坏。参见:
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 实例化一个 PSCheckContext
实例然后它忘记了它。除非 PSCCheckContext
的构造函数对系统有副作用(这不是一个好的编程习惯),否则这段代码没有任何效果(除了消耗 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
与构造函数参数绑定,因此从现在开始它应该可以注入到控制器中。
你也可以试试这个:
kernel.Bind<IPSCCheckContext>().ToConstructor(ctorArg => new PSCCheckContext(
"Name of Staff Application",
"Location of Application Server"));
相比 WithConstructorArgument
,我更喜欢这个,因为如果您更改了 arg 名称,您的 DI 绑定将不会中断。
我有一个 ASP.MVC 项目,我在其中使用 ninject 作为 IOC 容器。我已将绑定作为单独的 class 添加到 Infrastructure 文件夹中,如下所示:
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() class 只是将接口 classes 映射到您所期望的具体实现:
private void AddBindings()
{
...
_ninjectKernal.Bind<IPSCCheckContext>().To<PSCCheckContext>();
}
我遇到的问题是 PSCCheckContext class 中有 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
但是 none 似乎遇到了我的问题。
我做错了什么?
我无法删除额外的构造函数,因为它在不同的应用程序中,我认为它正被不同的系统使用。
这里是完整的 AccountController 构造函数
public class AccountController : BaseController
private readonly IPSCCheckContext _pscCheckContext;
public AccountController(IPSCCheckContext pscCheckContext)
{
this._pscCheckContext = pscCheckContext;
您问题中的代码已损坏。参见:
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 实例化一个 PSCheckContext
实例然后它忘记了它。除非 PSCCheckContext
的构造函数对系统有副作用(这不是一个好的编程习惯),否则这段代码没有任何效果(除了消耗 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
与构造函数参数绑定,因此从现在开始它应该可以注入到控制器中。
你也可以试试这个:
kernel.Bind<IPSCCheckContext>().ToConstructor(ctorArg => new PSCCheckContext(
"Name of Staff Application",
"Location of Application Server"));
相比 WithConstructorArgument
,我更喜欢这个,因为如果您更改了 arg 名称,您的 DI 绑定将不会中断。