具有数据库上下文的依赖注入。如何在常规类中获取数据库上下文

时间:2019-03-18 13:47:31

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

我已经在启动方法中为.net-core 2.1服务配置了数据库上下文。

val x = r.get(c.CITY)
val y = r.get(c.COUNTRY)
val z = r.get(c.DIVISION)
val a = r.get(c.RESIDENT)

if (x == 1 || y == 1 || z == 1 ) {
  "apple"
} else if (a.nonEmpty) {
  "mango"
} else {
  "banana"
}

现在我可以执行以下操作以在控制器中获取数据库上下文:

 services.AddDbContext<DatabaseContext>(options => options.UseSqlServer(Configuration.GetConnectionString(nameof(DatabaseContext))));

这很好。但是我该如何在普通的类中访问Database-Context呢?

var context = serviceProvider.GetService<DatabaseContext>();

我不想通过构造函数传递数据库上下文对象,也不想再次初始化DatbaseContext类。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

您应该通过构造函数(最好是接口)来获取依赖关系,例如IDatabaseContext,但以下代码示例基于您的代码。如果您将MyAccessClass添加为服务,例如services.AddTransient<MyAccessClass>(),然后在控制器中使用dependency injection,数据库上下文将由ASP.NET Core中的默认IoC容器自动注入到构造函数中。

您不应该依赖于IServiceProvider,原因是您的类不想假设实现,它只需要数据库上下文。让它依赖IServiceProvider会假定此上下文以及将来可能存在的依赖关系都来自ASP.NET Core中的IoC,情况可能并非如此(如果您稍后想将其作为类库发布,该怎么办? ?)。这将使MyAccessClass类很难在控制器外部进行测试和使用。

您在评论中说:

  

“ ...或在其他任何地方获取Database-Context类”

其他任何地方完全灵活,只需将上下文接受到构造函数中即可,因为您的类不知道其他任何地方在哪里,但是创建类的任何东西都知道!

ASP.NET Core中DI的示例

通过构造函数将上下文作为依赖项

public class MyAccessClass{
    private readonly DatabaseContext databaseContext;
    public MyAccessClass(DatabaseContext databaseContext) {
        this.databaseContext = databaseContext;
    }
}

添加为服务

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<MyAccessClass>();
}

注入控制器

public class MyController : Controller
{
    private readonly MyAccessClass myAccessClass;
    //Happily injected through DI
    public MyController(MyAccessClass myAccessClass)
    {
        this.myAccessClass = myAccessClass;
    }
}

或直接注入动作

public class MyController : Controller
{
    public MyController()
    {
    }

     public IActionResult MyAction([FromServices] MyAccessClass myAccessClass)
     {

     }
}