我有ProductController.cs
namespace AmazonProductAdvertisingAPI.WebUI.Controllers
{
public class ProductController : Controller
{
public ProductController(IProductCollection productCollection)
{
_productCollection = productCollection;
}
public static string Title
{
get
{
return _title;
}
set
{
_title = value;
}
}
public static int PageNumber
{
get
{
return _pageNumber;
}
set
{
_pageNumber = value;
}
}
public static int ItemsPerPage
{
get
{
return _itemsPerPage;
}
set
{
_itemsPerPage = value;
}
}
// GET: Product
public ActionResult List(int page = 1, string search = null)
{
ProductListViewModel model = new ProductListViewModel
{
Products = _productCollection.Products
.OrderBy(product => product.Title)
.Skip((page - 1) * pageSize)
.Take(pageSize),
PagingInfo = new PagingInfo
{
CurrentPage = page,
ItemsPerPage = pageSize,
TotalItems = _productCollection.Products.Count()
}
};
return View(model);
}
}
}
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>()
.WhenInjectedInto<ProductController>()
.WithConstructorArgument("title", ProductController.Title)
.WithConstructorArgument("pageNumber", ProductController.PageNumber)
.WithConstructorArgument("itemsPerPage", ProductController.ItemsPerPage);
}
}
}
AmazonProductCollection类有构造函数:
public AmazonProductCollection(string title, int pageNumber, int itemsPerPage)
我希望AmazonProductCollection从产品控制器的动作列表参数中获取自己的参数,因为当用户填充TextBoxt并点击按钮&#34;搜索&#34;在html视图形式。例如,我想使用参数字符串&#34;搜索&#34; from action列出并转移到AmazonProductCollection作为构造函数参数&#34; title&#34;。
我读过这篇文章:How to pass parameters to a transient object created by Ninject?,但我不明白在我的情况下如何创造相同的东西。
有人能帮我Ninject吗?
答案 0 :(得分:4)
一种解决方案是使用工厂。
工厂界面看起来像这样:
public interface IAmazonProductCollectionFactory
{
AmazonProductCollection Create(string title, int pageNumber, int itemsPerPage);
}
这样的界面将存在于控制器所在的同一个项目中(MVC项目)。
这种工厂的实施如下:
public class AmazonProductCollectionFactory : IAmazonProductCollectionFactory
{
private readonly IResolutionRoot m_ResolutionRoot;
public AmazonProductCollectionFactory (IResolutionRoot resolution_root)
{
m_ResolutionRoot = resolution_root;
}
public AmazonProductCollection Create(string title, int pageNumber, int itemsPerPage)
{
return resolution_root.Get<AmazonProductCollection>(
new ConstructorArgument("title", title),
new ConstructorArgument("pageNumber", pageNumber),
new ConstructorArgument("itemsPerPage", pageNumber));
}
}
AmazonProductCollectionFactory
将存在于Composition Root项目中。在您的情况下,这可能是相同的MVC项目。请注意,拥有依赖于IResolutionRoot
除了组合根之外的任何地方的工厂都是is considered an anti-pattern的服务地点示例。
现在,您需要将IProductCollection
注入IAmazonProductCollectionFactory
的构造函数而不是ProductController
,而让List
操作使用它来创建AmazonProductCollection
像这样的实例:
var productCollection = factory.Create(...);
其中factory
是您用于存储注入的IAmazonProductCollectionFactory
的实例变量的名称。
不要忘记向Ninject容器注册IAmazonProductCollectionFactory
。
请注意,您应该考虑创建符合List
操作要求的服务。例如,您可以将整个搜索逻辑包装在知道如何进行搜索的服务中,并让这样的服务担心通过抽象工厂创建AmazonProductCollection
。然后,不是将工厂注入控制器,而是将服务注入控制器。