如何从 MVC 控制器 class 传输到 NinjectDependencyResolver 具体类型参数中的 AddBindings()?
How transfer to AddBindings() in NinjectDependencyResolver concrete type argument from MVC controller class?
我有控制器classProductController.cs
namespace AmazonProductAdvertisingAPI.WebUI.Controllers
{
public class ProductController : Controller
{
private string _title = "Bible";
private IProductCollection _productCollection;
public int pageSize = 13;
public ProductController(IProductCollection productCollection)
{
_productCollection = productCollection;
}
public string Title
{
get
{
return _title;
}
set
{
_title = value;
}
}
// GET: Product
public ActionResult List(int page = 1)
{
return View(_productCollection.Products
.OrderBy(product => product.Title)
.Skip((page - 1)*pageSize)
.Take(pageSize)
);
}
}
}
class NinjectDependencyResolver.cs
namespace AmazonProductAdvertisingAPI.WebUI.Infrastructure
{
public class NinjectDependencyResolver : IDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver(IKernel kernelParam)
{
kernel = kernelParam;
AddBindings();
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
private void AddBindings()
{
// Create dependency here
kernel.Bind<IProductCollection>().To<AmazonProductCollection>()
.WithConstructorArgument("title", "Bible");
}
}
}
现在,NinjectDependencyResolver.cs 构造函数参数的方法 AddBindings() 是硬编码的。我想阅读 Title 属性并放入
private void AddBindings()
{
// Create dependency here
kernel.Bind<IProductCollection>().To<AmazonProductCollection>()
.WithConstructorArgument("title", "here_must_be_Title_field_from_ProductController");
}
我计划在用户填写搜索输入并单击按钮时设置此字段值 "Search"。
有人可以帮助并回答 NinjectDependencyResolver 如何更好地从 ProductController 获取价值吗?
您可以使用 WithConstructorArgument(string name, Func<Ninject.Activation.IContext, object> callback)
重载。
大意是:
- 获取控制器类型
- 创建该类型的实例
- 获取
Title
属性 的值
- Return 值
所以,结果是:
kernel.Bind<IProductCollection>()
.To<AmazonProductCollection>()
.WithConstructorArgument(
"title",
ninjectContext =>
{
var controllerType = ninjectContext.Request
.ParentRequest
.Service;
var controllerInstance = Activator.CreateInstance(controllerType);
return controllerInstance.GetType()
.GetProperty("Title")
.GetValue(instance);
});
但是,Activator.CreateInstance
将需要无参数构造函数来创建新实例,因此请将无参数构造函数添加到您的控制器中。
public class ProductController : Controller
{
...
public ProductController() {}
...
}
其他详细信息和第二个选择:
如果我们不想在绑定期间硬编码 Title
值,那么我们必须像前面的示例一样创建控制器的实例,因为这意味着我们想要获取它的 属性初始化前的值。或者您可以将控制器的 Title
s 存储在另一个资源文件中。那么你将不需要控制器实例,只需获取控制器类型,然后从该资源文件中获取所需的值。
但是,如果您愿意,也可以使用 WhenInjectedInto
作为:
kernel.Bind<IProductCollection>()
.To<AmazonProductCollection>()
.WhenInjectedInto<ProductController>()
.WithConstructorArgument("title", ProductController.Title);
kernel.Bind<IProductCollection>()
.To<AmazonProductCollection>()
.WhenInjectedInto<HomeController>()
.WithConstructorArgument("title", HomeController.Title);
为了在控制器中存储标题,您可以将其更改为 const:
public const string Title = "Bible";
我有控制器classProductController.cs
namespace AmazonProductAdvertisingAPI.WebUI.Controllers
{
public class ProductController : Controller
{
private string _title = "Bible";
private IProductCollection _productCollection;
public int pageSize = 13;
public ProductController(IProductCollection productCollection)
{
_productCollection = productCollection;
}
public string Title
{
get
{
return _title;
}
set
{
_title = value;
}
}
// GET: Product
public ActionResult List(int page = 1)
{
return View(_productCollection.Products
.OrderBy(product => product.Title)
.Skip((page - 1)*pageSize)
.Take(pageSize)
);
}
}
}
class NinjectDependencyResolver.cs
namespace AmazonProductAdvertisingAPI.WebUI.Infrastructure
{
public class NinjectDependencyResolver : IDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver(IKernel kernelParam)
{
kernel = kernelParam;
AddBindings();
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
private void AddBindings()
{
// Create dependency here
kernel.Bind<IProductCollection>().To<AmazonProductCollection>()
.WithConstructorArgument("title", "Bible");
}
}
}
现在,NinjectDependencyResolver.cs 构造函数参数的方法 AddBindings() 是硬编码的。我想阅读 Title 属性并放入
private void AddBindings()
{
// Create dependency here
kernel.Bind<IProductCollection>().To<AmazonProductCollection>()
.WithConstructorArgument("title", "here_must_be_Title_field_from_ProductController");
}
我计划在用户填写搜索输入并单击按钮时设置此字段值 "Search"。
有人可以帮助并回答 NinjectDependencyResolver 如何更好地从 ProductController 获取价值吗?
您可以使用 WithConstructorArgument(string name, Func<Ninject.Activation.IContext, object> callback)
重载。
大意是:
- 获取控制器类型
- 创建该类型的实例
- 获取
Title
属性 的值 - Return 值
所以,结果是:
kernel.Bind<IProductCollection>()
.To<AmazonProductCollection>()
.WithConstructorArgument(
"title",
ninjectContext =>
{
var controllerType = ninjectContext.Request
.ParentRequest
.Service;
var controllerInstance = Activator.CreateInstance(controllerType);
return controllerInstance.GetType()
.GetProperty("Title")
.GetValue(instance);
});
但是,Activator.CreateInstance
将需要无参数构造函数来创建新实例,因此请将无参数构造函数添加到您的控制器中。
public class ProductController : Controller
{
...
public ProductController() {}
...
}
其他详细信息和第二个选择:
如果我们不想在绑定期间硬编码 Title
值,那么我们必须像前面的示例一样创建控制器的实例,因为这意味着我们想要获取它的 属性初始化前的值。或者您可以将控制器的 Title
s 存储在另一个资源文件中。那么你将不需要控制器实例,只需获取控制器类型,然后从该资源文件中获取所需的值。
但是,如果您愿意,也可以使用 WhenInjectedInto
作为:
kernel.Bind<IProductCollection>()
.To<AmazonProductCollection>()
.WhenInjectedInto<ProductController>()
.WithConstructorArgument("title", ProductController.Title);
kernel.Bind<IProductCollection>()
.To<AmazonProductCollection>()
.WhenInjectedInto<HomeController>()
.WithConstructorArgument("title", HomeController.Title);
为了在控制器中存储标题,您可以将其更改为 const:
public const string Title = "Bible";