asp.net-mvc如何将转移到 AddBindings() 在 NinjectDependencyResolver 具体类型参数从 MVC 控制器类?

标签: Asp.net-MVC .Net C#
发布时间: 2017/3/25 4:22:01
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我有控制器类 ProductController.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)
                );
        }
    }
}

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

现在在 AddBindings() 的 NinjectDependencyResolver.cs 方法构造函数参数是硬编码。我想要读取标题属性和诸

private void AddBindings()
{
    // Create dependency here
    kernel.Bind<IProductCollection>().To<AmazonProductCollection>()
                                     .WithConstructorArgument("title", "here_must_be_Title_field_from_ProductController");
}

我计划设置此字段的值,当用户填充搜索输入,然后单击"搜索"按钮。

谁能帮和如何更好地做那 NinjectDependencyResolver 的答案可以从 ProductController 中获得价值吗?

解决方法 1:

您可以使用 WithConstructorArgument(string name, Func<Ninject.Activation.IContext, object> callback) 过载。

总的想法是︰

  • 获取类型的控制器
  • 创建该类型的实例
  • 获得 Title 属性的值
  • 返回它的值

所以,结果是︰

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 将需要 paramterless 构造函数来创建一个新的实例,那么将 parametrless 构造函数添加到您的控制器。

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";
赞助商