【问题标题】:How to inject a class with constructor parameter in MVC?如何在 MVC 中注入带有构造函数参数的类?
【发布时间】:2017-05-01 00:43:12
【问题描述】:

如果这个问题已经得到解答,我们深表歉意。我已经搜索过,但找不到解决方案。

如何在#5 中的 MVC 中注入带有构造函数参数的类?甚至有可能吗?

对于下面的代码,由于缺少 sqlContext 参数,无法构造注入的 MyHelper1,因此会报错。

这是我的(简化的)对象:

// 1. HELPER CLASS TO INJECT
public class MyHelper1 : HelperBase, IHelper
{
    public MyHelper1(IHelperSqlContext sqlContext) : HelperBase(sqlContext)
    public override string HelperTag { get; } = "HELPER1";
    . . .
}

// 2. BASE HELPER
public abstract class HelperBase 
{
    private IHelperSqlContext _sqlContext;
    abstract public string HelperTag { get; }
    public HelperBase(IHelperSqlContext sqlContext)
    {
        _sqlContext = sqlContext;
    }
    public List<HelperRecords> GetRecords(Id id)
    {
        return _sqlContext.GetRecords(id);
    }
    . . . 
}

// 3. INTERFACE
public interface IHelper
{
    . . . 

}

// 4. CONTROLLER
public class MyController : Controller
{
    IHelper _myHelper
    public MyController(IHelper myHelper)
    {
         _myHelper = myHelper;
    }

    public IActionResult Index(Id id)
    {
        var model = new MyViewModel();
        model.MyRecords = _myHelper.GetRecords(id);
        return View(model);
    }
}

// 5. STARTUP - INJECT PART
public class Startup
{
    . . .
    public void ConfigureServices(IServiceCollection services)
    {
        . . . 
        // How to pass MyHelper1 class with IHelperSqlContext here???
        services.AddTransient<IHelper, MyHelper1>();
    }  
}

感谢任何帮助。提前致谢。

【问题讨论】:

  • 您应该以official Microsoft Documentation 开头。这是相当不错的。如果您之后有任何具体问题,请在此处发布新问题。
  • 谢谢@Steven。我读过它,我认为我的问题类似于那部分 => public CharacterRepository(ApplicationDbContext dbContext) 。 .在 ConfigureServices 中, services.AddDbContext(options => options.UseInMemoryDatabase() );这 => services.AddScoped();就像 NKosi 下面的建议一样。我的问题是出现编译错误,提示“IServiceCollection 不包含 AddDbContext”。潜在修复显示“添加包 MS EntityFrameworkCore 1.1.0。我们没有使用实体框架。

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


【解决方案1】:

是的,您需要做的就是在 Startup 类的 ConfigureServices 方法中注册所有依赖项(这也意味着您的依赖项依赖项)。

所以在这种情况下你需要像这样添加一行。

services.AddTransient<IHelperSqlContext, MyHelperSqlContext>();

您可以在 Microsoft 文档中获取有关依赖注入 here 的更多信息。

【讨论】:

  • 谢谢罗伊。我尝试了它并收到类似“InvalidOperationException:尝试激活'MyNameSpace.MyHelperSqlContext'时无法解析类型'System.String'的服务”的错误。但这可能是另一个问题(如何正确传递)。我会阅读链接并尝试找出答案,如果它有效,那么我会将您的帖子作为答案。
【解决方案2】:

所有依赖项都需要在 DI 容器中注册,以便它知道如何解析它及其依赖项。

以下假设抽象被实现为 DbContext 派生类。

public class Startup {
    //. . .

    public void ConfigureServices(IServiceCollection services) {

        //. . . 

        //Register your context with dependency injection
        services.AddDbContext<HelperSqlDbContext>(options =>    
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))
        );
        //register the context with its abstraction
        service.AddScoped<IHelperSqlContext, HelperSqlDbContext>()

        services.AddTransient<IHelper, MyHelper1>();
    }  
}

【讨论】:

  • 谢谢@Nkosi。它在 AddDbContext 行上向我抛出了一个错误 =>“错误 CS1061 'IServiceCollection' 不包含 'AddDbContext' 的定义并且没有扩展方法 'AddDbContext' 接受类型为 'IServiceCollection' 的第一个参数”(您是否缺少using 指令或程序集引用?)”。供参考。我们没有使用 EntityFramework。
猜你喜欢
  • 2021-02-04
  • 1970-01-01
  • 1970-01-01
  • 2018-02-25
  • 1970-01-01
  • 2019-03-10
  • 1970-01-01
  • 2011-10-17
  • 1970-01-01
相关资源
最近更新 更多