为什么看起来该接口提供了实现?

时间:2019-09-25 01:27:32

标签: c# oop asp.net-core dependency-injection

我遵循了一个教程,并使用EF Core构建了后端,并实现了存储库模式。

首先,我创建了一个存储库接口和一个提供基本CRUD方法的存储库基类。然后,我为与这些特定类上的数据进行交互所需的任何自定义方法,为我的每个实体创建了单独的接口和存储库。

第二,我创建了一个接口和一个名为IRepositoryWrapper和RepositoryWrapper的具体类。定义要返回的存储库和保存方法,然后实现检索存储库和保存更改方法的实现。

最后,我创建了一个控制器,并将IRepositoryWrapper注入到控制器的构造函数中。

我的问题是:为什么将接口注入控制器确实有效?由于接口仅提供定义,因此为什么实际实现似乎附带了定义?我觉得我应该改为注入具体的类RepositoryWrapper。

https://code-maze.com/net-core-web-development-part4/#repository

这正常工作,我只是在问一个面向对象的问题。

public interface IRepositoryWrapper
{
    IScenarioRepository Scenario { get; }
    IConditionRepository Condition { get; }

    void Save();
}

public class RepositoryWrapper : IRepositoryWrapper
{
    private EvaluatorContext _evaluatorContext;
    private IConditionRepository _condition;
    private IScenarioRepository _scenario;

    public RepositoryWrapper(EvaluatorContext evaluatorContext)
    {
        this._evaluatorContext = evaluatorContext;
    }

    public IScenarioRepository Scenario
    {
        get
        {
            if (_scenario == null)
            {
                _scenario = new ScenarioRepository(_evaluatorContext);
            }

            return _scenario;
        }
    }

    public IConditionRepository Condition
    {
        get
        {
            if (_condition == null)
            {
                _condition = new ConditionRepository(_evaluatorContext);
            }

            return _condition;
        }
    }

    public void Save()
    {
        _evaluatorContext.SaveChanges();
    }
}

控制器类:


[Route("api/[controller]")]
[ApiController]
public class ScenariosController : ControllerBase
    {

        private IRepositoryWrapper _repositoryWrapper;

        //What I am calling injecting this interface into the constructor
        public ScenariosController(IRepositoryWrapper repositoryWrapper)
        {
            this._repositoryWrapper = repositoryWrapper;
        }

        [HttpGet]
        public IEnumerable<Scenario> FindAll()
        {

            return this._repositoryWrapper.Scenario.FindAllWithIncludes();
        }

    }

1 个答案:

答案 0 :(得分:2)

  

为什么将接口注入控制器实际上有效?由于接口仅提供定义,因此为什么实际实现似乎附带了定义?

该接口定义了签名,因此可以通过多种方式实现。

当您将带有具体实现的类传递给Controller Constructors Interface参数时,如果该类继承该接口,它将知道所有方法均可用。 这就是它所知道的方式。

  

我觉得我应该注入具体的类RepositoryWrapper。

是的,当您连接DI时,您会钩住具有实现的类。 Interface参数将接受任何实现接口方法的类。

为什么?要点是关注点分离。使用接口使您可以模拟实施,这些显着简化了单元测试。

它们还具有灵活性,例如在美国,税号是11位数字,在澳大利亚是8位数字。好吧,您可以为美国提供11位功能,为Oz提供8位功能的课程。如果没有接口,则只能传入11或8-可能会迫使您拥有两个以相同方式操作且行为稍有不同的类。使用接口可为您提供实现的灵活性。

它是SOLID原理,接口隔离原理:低耦合,高内聚和依赖反转原理的一部分:抽象不应依赖细节。