15

Example:

public abstract class BaseControler : Controller
{
    public IUnitOfWork UnitOfWork { get; set; }
}

public class HomeController : BaseControler
{
    readonly IUserRepository _userRepository;

    // :-)
    public HomeController(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }
}

We all know that we have to use Constructor Injection when the dependency is required. If it is an optional dependency we can use Property Injection instead.

But what should you do when only your base class requires the dependency?

When you would use Constructor Injection you would in my opinion pollute all derived classes.

public abstract class BaseControler : Controller
{
    readonly IUnitOfWork _unitOfWork;

    public BaseControler(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }
}

public class HomeController : BaseControler
{
    readonly IUserRepository _userRepository;

    // :-(
    public HomeController(IUserRepository userRepository, 
       IUnitOfWork unitOfWork) : base(unitOfWork)
    {
        _userRepository = userRepository;
    }
}

Is it approperiate to use Property Injection in a base class when a dependency is only required in the base class?

Rookian
  • 19,841
  • 28
  • 110
  • 180

2 Answers2

16

You are not polluting the derived class. You are explicitly stating to the consumer that this class cannot function without this dependency.

If the base class requires this dependency in order to function properly, since the derived class derives from this base class, it implicitly requires this dependency as well. So the second example is the correct way. You shouldn't be using property injection for something that is a required dependency.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • 1
    I see your point, but the problem I will get are a lot of constructor parameters. The point is that the derived classes are not talking directly to the dependency, instead of the base class. So I would distinguishing between direct calls to a dependency and indirect calls to a dependency. – Rookian May 04 '12 at 13:39
  • 1
    @Rookian, if you get into a situation where you are having multiple constructor parameters you might consider creating a service that will aggregate those dependencies and then inject only the service into the constructor. – Darin Dimitrov May 04 '12 at 13:41
  • 5
    +1 Favor composition over inheritance. If it becomes a problem with too many constructor parameters, blame your inheritance strategy, not Constructor Injection. – Mark Seemann May 04 '12 at 13:42
  • 1
    @Rookian, see my answer - derived class is talking to dependency, because it is also base class. You just pushed all duplicated logic (which uses dependency) to base class. – Sergey Berezovskiy May 04 '12 at 13:44
3

Actually your derived class IS a base class. There is no some other object somewhere. When you pass something to base constructor, you actually initialize same object. And it shows to clients what your instance depends on:

public HomeController(IUserRepository userRepository, IUnitOfWork unitOfWork)

There is ONE instance, which depends on two things: user repository, and unit of work. Call to base class constructor just removes initialization duplication from your derived classes.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459