当一个依赖项仅在基类中需要时,使用属性注入来注入依赖项是否合适?

15

例子:

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

public class HomeController : BaseControler
{
    readonly IUserRepository _userRepository;

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

我们都知道在依赖关系是必需的时,我们必须使用构造函数注入。如果是一个可选的依赖关系,则可以使用属性注入

但是当只有基类需要该依赖项时,应该怎么做呢?

在我看来,如果您使用构造函数注入,那么您将污染所有派生类。

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;
    }
}

当依赖项仅在基类中需要时,是否适合在基类中使用属性注入

2个回答

16

您不是在污染派生类。您明确告知消费者,该类不能在没有此依赖项的情况下正常运行。

如果基类需要该依赖项才能正常运行,那么由于派生类从该基类派生,因此它也隐式地需要该依赖项。因此,第二个示例是正确的方式。您不应该为必需的依赖项使用属性注入。


1
我理解你的观点,但我将面临的问题是有很多构造函数参数。关键是派生类不直接与依赖项交互,而是与基类交互。因此,我会区分对依赖项的直接调用和间接调用。 - Rookian
1
@Rookian,如果你遇到有多个构造函数参数的情况,你可以考虑创建一个服务来聚合这些依赖项,然后只将服务注入到构造函数中。 - Darin Dimitrov
5
优先使用组合而非继承。如果由于构造函数参数过多而出现问题,请归咎于继承策略,而不是构造函数注入。 - Mark Seemann
1
@Rookian,看看我的回答——派生类正在与依赖项交互,因为它也是基类。你只是把所有使用依赖项的重复逻辑推到了基类中。 - Sergey Berezovskiy

3

实际上,您的派生类就是一个基类。并不存在其他对象。当您将某些内容传递给基类构造函数时,实际上是在初始化同一对象。这向客户端展示了您的实例依赖于什么:

public HomeController(IUserRepository userRepository, IUnitOfWork unitOfWork)

有一个实例,它依赖于两个东西:用户存储库和工作单元。调用基类构造函数只是从派生类中删除初始化重复。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接