【问题标题】:Why Dependency Injection doesn't know about my repo?为什么依赖注入不知道我的仓库?
【发布时间】:2018-10-12 13:42:00
【问题描述】:

我的情况很奇怪。我需要为我的 .net 核心应用程序使用 Entity Framework 6.2。

一个普通的控制器

public class SampleApiController : BaseController
{
   // use _repo and other stuff
}

基本控制器

public class BaseController : Controller
    {
        protected IRepo_repository;

        public BaseController(IRepo repository)
        {
            _repository = repository;
        }

        public BaseController() : this(null)
        {

        }
    }

应用 DBContext

public class SampleContext : DbContext
    {
        public SampleContext(string connectionString)
            :base(connectionString)
        {
            try
            {   
                this.Database.Log = (s) => System.Diagnostics.Debug.Write(s);
            }
            catch (Exception e)
            {
                //CurrentLogger.Log.Error(e);
            }
        }

        public DbSet<Test1> Test1s { get; set; }
        public DbSet<Test2> Test2s { get; set; }
    }

存储库界面

public interface IRepo
    {
// methods definition
}

存储库类

public interface Repo : IRepo
    {
// methods implementation
}

Startup.cs -> ConfigureServices 方法

services.AddScoped<SampleContext>((s) => new SampleContext(configuration["ConnectionStrings:SampleApp"]));
        services.AddScoped<IRepo, Repo>();


在这张图片中,您可以看到存储库参数为空...未使用 Repo 实例初始化...(!!!在这张图片中 IRepo 是 IRepositoryBase)

解决方案!

正如 CodeNotFound 和 Riscie 在 cmets 中所说,问题在于 BaseController 被初始化为 null...谢谢大家!

【问题讨论】:

  • 你的 Repo 没有实现 IRepo 接口
  • Repo 是一个接口 .. 它应该是类并实现 IRepo
  • 这里有一个默认构造函数的目的是什么?我认为 DI 采用默认存储,调用 this(null) Tha 是您获得 null 值的地方。在此处设置断点并进行测试。
  • 您注册的唯一服务是IRepo =&gt; Repo,但您正在注入IRepositoryBase。你还没有告诉 DI 容器如何处理IRepositoryBase
  • FWIW,不要使用存储库模式。存储库模式用于处理 SQL 等低级别的东西。 ORM,如实体框架,已经实现了存储库模式。这就是你的DbSets。将其包装在存储库中只是一种无用的抽象,它为您的代码增加了额外的熵(更多需要维护,更多需要测试),没有任何好处(无论哪种方式,您仍然依赖 EF)。

标签: entity-framework asp.net-core dependency-injection


【解决方案1】:

试试这个:

存储库界面

public interface IRepo
{
    // methods definition
}

存储库类 我已经将它从接口更改为类,并使其实现了 IRepo 接口

public class Repo : IRepo
{
    // methods implementation
}

编辑: 同时删除第二个构造函数

public class BaseController : Controller
{
    protected IRepo_repository;

    public BaseController(IRepo repository)
    {
        _repository = repository;
    }

    //second constructor most likely introduces the problem
}

【讨论】:

  • 对不起,我忘了把它放在这个示例中。在代码中是。
  • 在您的BaseController 构造函数中(在屏幕截图中),您还实例化了IRepositoryBase 而不是IRepo
  • 另外,为什么你有一个构造函数用 null 来初始化你的 BaseController? (见我的编辑)
【解决方案2】:

您通常将 IRepoSampleApiController 传递到 BaseController

根据我的理解,BaseController 中不需要没有参数构造函数。如果是这样,您可能希望将其删除以防止 _repository 成为 null

public class SampleApiController : BaseController
{
    public SampleApiController(IRepo repository) 
        : base(repository)
    {
    }
}

public class BaseController : Controller
{
    protected IRepo _repository;

    public BaseController(IRepo repository)
    {
        _repository = repository;
    }

    /*public BaseController() : this(null)
    {    
    }*/
}

public interface IRepo
{
    // methods definition
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多