Reputation: 15676
I've get a base class like so...
public class BaseController : Controller
{
private readonly IUserRepository userRepository;
public BaseController(IUserRepository userRepository)
{
this.userRepository = userRepository;
}
}
I want all of my MVC controllers to inherit from this class. Is there some way that I can avoid having to supply the 'userRepository' instance to the base class from every sub-classes constructor like this?
public HomeController(IUserRepository repository) : base(repository)
{
}
Cheers, Ian.
Upvotes: 1
Views: 211
Reputation: 15676
I think I've got it... when registering the contollers for the IoC Container, check whether they inherit from the base class and then if so add some property injection to the mapping. Voila!
I've since pondered though as to whether this is a bad design. Yes it saves some typing and makes things look simpler but its opening up some possibly significant side effects into a sub-classes operations. i.e. the sub-class is dependent on objects that haven't come via the constructor or via method parameters. They may or may not even be there.
Upvotes: 0
Reputation: 60448
You can create a custom ControllerFactory and register it in global.asax
ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory())
The content of your CustomControllerFactory
public class CustomControllerFactory : DefaultControllerFactory
{
private readonly IUserRepository userRepository;
public override IController CreateController(RequestContext requestContext, string controllerName)
{
return new BaseController(userRepository);
}
}
This is also useful if you are using Dependency Injection.
More Information:
Simple Dependency Injection using a Custom MVC Controller Factory
Upvotes: 0
Reputation: 1565
You can use some wrapper class that inherites from BaseController and put some (what???) object to userRepository
public class WrapperController: BaseController
{
public WrapperController()
{
base.userRepository = someObject;
}
}
Upvotes: 0
Reputation: 10400
The only way I am aware of would be not to pass IUserRepository as a parameter of the base class and instead instantiating it in the base class using:
protected readonly IUserRepository UserRepository = BindingFactory.GetInstance<IUserRepository>();
Where GetInstance<T>()
calls the Resolve() method
of the container. But this would depend on the type of IOC you are using.
Upvotes: 0
Reputation: 4459
I've you talk about not having to duplicate the constructor in the derived class, than the answer would be no. You could always provide a default constructor in the base class, which is using some sort of DI-container to get hold of an IUserRepository
instance.
If you safe some time typing, you can always provide a custom T4 template that includes the constructor for you. You can find an example here: http://www.hanselman.com/blog/ModifyingTheDefaultCodeGenerationscaffoldingTemplatesInASPNETMVC.aspx (although this mainly focuses on the view, the same goes for adding controllers).
Upvotes: 1