Ian Warburton
Ian Warburton

Reputation: 15676

Avoiding having to supply base class parameters in C#

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

Answers (5)

Ian Warburton
Ian Warburton

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

dknaack
dknaack

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

zzfima
zzfima

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

Digbyswift
Digbyswift

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

J. Tihon
J. Tihon

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

Related Questions