3

У меня есть ProductController.csКак передать параметры действия контроллера бетонному типу Ninject?

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 и нажимает кнопку «Поиск» в html-view form. Например, я хочу использовать строку параметров «поиск» из списка действий и передать в AmazonProductCollection как параметр конструктора «title».

Я прочитал это сообщение: How to pass parameters to a transient object created by Ninject?, но я не понимаю, как можно создавать такие же вещи в моей ситуации.

Может ли кто-нибудь помочь мне с Ninject?

ответ

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.

Не забудьте зарегистрировать IAmazonProductCollectionFactory с контейнером Ninject.

Обратите внимание, что вам следует подумать о создании службы, которая соответствует требованиям действия List. Например, вы можете обернуть всю логику поиска внутри службы, которая знает, как выполнить поиск, и позволить такой услуге беспокоиться о создании AmazonProductCollection через абстрактный завод. А затем вместо того, чтобы вводить завод в контроллер, вы вводите эту услугу в контроллер.

+0

Где лучше поставить эти классы заводов? В проекте домена или mvc? Не могли бы вы указать папку, которая лучше использовать для конронов? –

+1

Завод должен жить в корне композиции. Это как можно ближе к точке входа приложения. Проект MVC является подходящим местом. Где у вас есть класс «NinjectDependencyResolver»?Вы можете поместить завод в ту же папку этого класса. –

+0

Спасибо! Ваш ответ помогает мне! –