Reputation: 348
I have 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 class have constructor:
public AmazonProductCollection(string title, int pageNumber, int itemsPerPage)
I want that AmazonProductCollection get own parameters from action List parameters from Product controller, because some of this it gets when user fill TextBoxt and click to button "Search" in html-view form. For example I want use parameter string "search" from action List and transfer to AmazonProductCollection as constructor parameter "title".
I read this post: How to pass parameters to a transient object created by Ninject?, but I don't understand how possible to create same things in my situation.
Can somebody help me with Ninject?
Upvotes: 4
Views: 1064
Reputation: 27871
One solution is to use a factory.
The factory interface would look something like this:
public interface IAmazonProductCollectionFactory
{
AmazonProductCollection Create(string title, int pageNumber, int itemsPerPage);
}
Such interface would live in the same project where the controller is (the MVC project).
The implementation of such factory would look like this:
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));
}
}
The AmazonProductCollectionFactory
would live inside the Composition Root project. In your case, this is probably the same MVC project. Please note that having such factory that depends on IResolutionRoot
any place except for the composition root is an example of service location which is considered an anti-pattern.
Now, instead of IProductCollection
, you need to inject IAmazonProductCollectionFactory
into the constructor of the ProductController
and let the List
action use it to create an AmazonProductCollection
instance like this:
var productCollection = factory.Create(...);
where factory
is the name of the instance variable that you used to store the injected IAmazonProductCollectionFactory
.
Don't forget to register IAmazonProductCollectionFactory
with the Ninject container.
Please note that you should consider creating a service that matches the requirements of the List
action. For example, you can wrap the whole search logic inside a service that knows how to do the search and let such service worry about creating the AmazonProductCollection
via the abstract factory. And then, instead of injecting the factory into the controller, you would inject the service into the controller.
Upvotes: 5