Embed a controller with arguments in the constructor

I do not always have static values ​​(slogan, banner, description ...) and PartialViews (block_head, block_footer, block_right) where I have to display it. Therefore, I need to transfer a large collection of these values ​​to Partial in each Action, and this is not very good for me.

I found an interesting solution here: http://www.asp.net/mvc/tutorials/passing-data-to-view-master-pages-cs , partially "Good Solution". I could move all the initialization of these values ​​to the ApplicationController and implement it from my controllers.

But I would like to go ahead and initialize my interfaces in the ApplicationController too :) If I could do this, I think it should be fantastic. I use Ninject, therefore, some code:

public abstract class ApplicationController : Controller { // // GET: /Application/ private readonly IModuleRepository _moduleRepository; public IModuleRepository moduleRepository { get { return _moduleRepository; } } public ApplicationController(IModuleRepository moduleRepository) { _moduleRepository = moduleRepository; foreach (var module in _moduleRepository.GetAllModules()) ViewData[module.name] = module.value; } } 

Implementation:

 public class HomeController : ApplicationController { //I can use here moduleRepository without HomeController initialization } 

Only one problem, I don’t know how to implement ApplicationController if it has arguments. Is this a good way and is this a solution to my problem? In the future I am going to install 5-7 interfaces and have about 10-15 controllers, so it would be very useful to initialize them all in ApplicationController and implement them in another. Thank you, sorry if the questionnaire is stupid.


Ok by adding:

Now, if I have 10 interfaces, it should be something like this:

 public class HomeController { private IModuleRepository _moduleRepository; private IBookRepository _bookRepository; private ITableRepository _tableRepository; private IClassRepository _classRepository; private IRoomRepository _roomRepository; private IUserRepository _userRepository; private IWindowRepository _windowRepository; private IChairRepository _chairRepository; private IDoorRepository _doorRepository; private IWCRepository _wcRepository; public HomeController(IModuleRepository moduleRepository, IBookRepository bookRepository, ITableRepository tableRepository, IClassRepository classRepository, IRoomRepository roomRepository, IUserRepository userRepository, IWindowRepository windowRepository, IChairRepository chairRepository, IDoorRepository doorRepository, IWCRepository wcRepository) { _moduleRepository = moduleRepository; _bookRepository = bookRepository; _tableRepository = tableRepository; _classRepository = classRepository; _roomRepository = roomRepository; _userRepository = userRepository; _windowRepository = windowRepository; _chairRepository = chairRepository; _doorRepository = doorRepository; _wcRepository = wcRepository; } public ActionResult Index() { ViewBag.Windows = _windowRepository.GetAllWindows(); ViewBag.Doors = _doorRepository.GetAllDoors(); // etc return View(); } } 

And I have to initialize this in each of my controllers, where I need to use these repositories (Home, Admin, ...).

So, if I could do something like this:

 public class HomeController : ApplicationController { public ActionResult Index() { ViewBag.Windows = windowRepository.GetAllWindows(); ViewBag.Doors = doorRepository.GetAllDoors(); return View(); } } 

And initialize only once here:

 public abstract class ApplicationController : Controller { public ApplicationController(IModuleRepository moduleRepository, IBookRepository bookRepository, ITableRepository tableRepository, IClassRepository classRepository, IRoomRepository roomRepository, IUserRepository userRepository, IWindowRepository windowRepository, IChairRepository chairRepository, IDoorRepository doorRepository, IWCRepository wcRepository) { // Initialize repositories just one time here } } 

this may be very good, but I need to pass arguments in the constructor of the implementing class

+4
source share
3 answers

You can always use the Ninject dependency resolver to get an instance, so instead of _:

 public ApplicationController(IModuleRepository moduleRepository, IBookRepository bookRepository, ITableRepository tableRepository, IClassRepository classRepository, IRoomRepository roomRepository, IUserRepository userRepository, IWindowRepository windowRepository, IChairRepository chairRepository, IDoorRepository doorRepository, IWCRepository wcRepository) { // Initialize repositories just one time here } 

you could do

 protected readonly IModuleRepository ModuleRepository; // same for the rest... public ApplicationController() { this.ModuleRepository = MvcApplication.Container.Get<IModuleRepository>(); // same for rest or your modules. } 

if you are on MVC3 this will be:

 protected readonly IModuleRepository ModuleRepository; public ApplicationController() { this.ModuleRepository = DependencyResolver.Current.GetService<IModuleRepository>(); // same for rest or your modules. } 
+1
source

Looks like you can talk about Constructor Injection . The constructor of your subtype can invoke the constructor of your base type to enter IModuleRepository

 public class HomeController : ApplicationController { public HomeController(IModuleRepository moduleRepository) : base(moduleRepository) { //other constructor code here } public HomeController() : this(null) { //default constructor } } public abstract class ApplicationController : Controller { public IModuleRepoistory _moduleRepository { get; private set; } public ApplicationController(IModuleRepository moduleRepository) { _moduleRepository = moduleRepository ?? new DefaultModuleRepository(); //... } } 

If in the future you intend to implement many interfaces, you will probably be better off using the Setter injection

+3
source

Yeap, this is really better than the first answer, because now I have:

 public abstract class ApplicationController : Controller { protected readonly IModuleRepository _moduleRepository; public IModuleRepository moduleRepository { get { return _moduleRepository; } } public ApplicationController() { this._moduleRepository = DependencyResolver.Current.GetService<IModuleRepository>(); foreach (var module in _moduleRepository.GetAllModules()) ViewData[module.name] = module.value; } } 

And I do not need to make any changes to my controllers. Just implement and can work with repositories:

 public class HomeController : ApplicationController { public ActionResult Index() { ViewBag.Modules = moduleRepository.GetAllModules(); return View(); } } 

And in all my controllers, I have a complete collection of ViewData values ​​that are passed to PartialViews. thanks alot, awesome :)!

+1
source

Source: https://habr.com/ru/post/1342793/


All Articles