Implement controller with arguments in constructor
I have alot of not always static values (slogan, banner, description...) and PartialViews (block_head, block_footer, block_right), where i should display it. So, i need to pass big collection of this values into Partial in every Action and it's not very good for me.
I've found interesting solution here: http://www.asp.net/mvc/tutorials/passing-data-to-view-master-pages-cs , in part "Good solution". I could move all initialization of this values in ApplicationController and Implement it from my controllers.
But, i'd like to go forward and initialize my Interfaces in ApplicationController too :) If i could do it, i think it should be fantastic. I use Ninject, so, 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;
}
}
Implementing:
public class HomeController : ApplicationController
{
//I can use here moduleRepository without HomeController initialization
}
Just one problem, i don't know how to Implement ApplicationController, if it has arguments. Is it good way and is it any solution for my problem? In future i'm going to set 5-7 Interfaces and have about 10-15 Controllers, so it could be very good to Initialize them all in ApplicationController and Implement in other. Thx, sorry if the questiong is stupid.
Ok, adding:
Now, if i have 10 interfaces, it should be like this:
public class HomeController
{
private IModuleRepository _moduleRepository;
private IBookRepository _bookRepository;
private ITableRepository _tableRepository;
private IClassRepository _classRepository;
private IRoomRepository _roomRepository;
priv开发者_Go百科ate 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();
// e.t.c.
return View();
}
}
And i have to initialize this in each of my Controller, where i need to use this repositories (Home, Admin, ...).
So, if i could to make something like this:
public class HomeController : ApplicationController
{
public ActionResult Index()
{
ViewBag.Windows = windowRepository.GetAllWindows();
ViewBag.Doors = doorRepository.GetAllDoors();
return View();
}
}
And initialize just one time 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
}
}
it could be very good, but i need to pass arguments in constructor of implementing class
It looks like you may be talking about Constructor Injection. The constructor of your sub type can invoke the constructor of your base type in order to inject the 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 future you intend to inject a lot of interfaces then you'll probably be better off using Setter Injection
You could always use the Ninject dependency resolver to get the 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're on MVC3 it would be:
protected readonly IModuleRepository ModuleRepository;
public ApplicationController()
{
this.ModuleRepository = DependencyResolver.Current.GetService<IModuleRepository>();
// same for rest or your modules.
}
Yeap, it's really better than 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 don't need to make any changes in my controllers. Just implement and could work with repositories:
public class HomeController : ApplicationController
{
public ActionResult Index()
{
ViewBag.Modules = moduleRepository.GetAllModules();
return View();
}
}
And in all of my Controllers i have full collection of ViewData values, which passing in PartialViews. Thx alot, awesome :) !
精彩评论