何时使用DI而不是抽象继承?

时间:2015-06-10 21:11:47

标签: c# dependency-injection abstract-class

我正在设计一个使用抽象属性的类来提供对字段的访问点。以下是我的代码片段:

public abstract class PageBroker : WebBroker
{
    public abstract IPageProvider Provider { get; }
}

public class ArticleBroker : PageBroker
{
     public override IPageProvider Provider { get; } = new ArticleProvider();
}

我意识到我可以重构这个来代替使用DI,就像这样:

public class PageBroker : WebBroker
{
    public PageBroker(IPageProvider provider)
    {
        this.Provider = provider;
    }

    public IPageProvider Provider { get; private set; }

    // implementation...
}

// no derived class, just new PageBroker(new ArticleProvider())

在什么情况下,一种技术适合另一种技术?

3 个答案:

答案 0 :(得分:3)

我同意BJ Safdie的回答。

那就是说,我认为主要区别在于,在第一个实现中,ArticleBroker与IPageProvider的特定实现(即ArticleProvider)相结合。如果是这样的话,我认为没问题。但是,如果您想在运行时提供IPageProvider的实现(无论是在生产代码中还是在通过模拟/伪造的单元测试中),那么注入依赖项是更好的选择。

答案 1 :(得分:2)

这是关于有利于构成而不是继承,这是一个很好的指导方针。我建议由于PageBroker 一个IPageProvider,你应该使用DI。该类的用户可以提供没有继承的替代实现,比如注入测试IPageProvider。仅仅因为这个原因,我会选择DI。

如果存在基于IPageProvider的存在差异,那么使用不同的提供者在语义上需要来反映关系(PageBroker的子类型),那么我会去抽象课。

答案 2 :(得分:1)

如前所述,我会用DI填充您的提供商。那说你想通过抽象类获得什么?如果它只是注入IPageProvider那么真的没什么好说的。

但是,如果您有其他常见的方法,这些方法非常特定于WebBrokers或PageBrokers,那么为什么不同时使用它们呢?

例如:

public abstract class WebBroker
{
    private IPageProvider _pageProvider;

    protected WebBroker(IPageProvider pageProvider)
    {
        _pageProvider = pageProvider;
    }

    public override void CommonThing(int someData)
    {
       var result = _pageProvider.CommonMethod(someData);
       //do something with result
    }
}

现在所有的WebBrokers都有CommonThing方法,该方法使用DI传入的_pageProvider。