繁体   English   中英

为什么我的 EF Core DbContext 不受 DI 约束?

[英]Why is my EF Core DbContext not bound by DI?

我有一个 Azure 函数应用程序,其函数在 blob 触发器上运行。 我已经证明这个函数可以通过 Azure 门户运行,并且可以毫无问题地响应这个 blob 触发器……或者至少确实如此。

现在我已经添加了使用 EF Core (2.2.4) 的功能,它在本地调试和发布到 Azure 时都会出现以下错误:

Microsoft.Azure.WebJobs.Host:索引方法“ParseThings”时出错。 Microsoft.Azure.WebJobs.Host:无法将参数“context”绑定到类型 AvastusContext。 确保绑定支持参数类型。 如果您使用绑定扩展(例如 Azure Storage、ServiceBus、Timers 等),请确保您已在启动代码(例如 builder.AddAzureStorage()、builder.AddServiceBus() 中调用了扩展的注册方法)、builder.AddTimers() 等)。

我有一个Startup类,按照 Azure Function App 文档here 的指示,除了以下行代替他们配置的示例服务外,我已经按照他们的示例进行了操作:

[assembly: FunctionsStartup(typeof(AvstFunctionApp.Startup))]

namespace AvstFunctionApp
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddDbContext<AvastusContext>(options => options.UseSqlServer(Environment.GetEnvironmentVariable("AvastusDb")));
        }
    }
}

我的功能开始:

public static class ParseThings
{
    [FunctionName("ParseThings")]
    public static void Run([BlobTrigger("summaries/{name}", Connection = "StorageConnectionString")]Stream myBlob, string name, ILogger log, AvastusContext context)

我可以证实, AddDbContext线在调试器击中,所以大概有一些错误发生在幕后这里,还是我做的事情令人难以置信的愚蠢。

我尝试过但没有奏效的事情包括:

  • .BuildServiceProvider(true)添加到AddDbContext
  • 使用WebJobsStartup而不是最近宣传的FunctionsStartup
  • 降级到 .NET Core 2.2.0
  • 将 Function 类和Run方法从静态更改为实例
  • 修复注入的AvastusContext错误命名空间

还值得注意的是,在这个 Function App 项目中还有另外两个函数似乎没有任何严重问题,而且我已经能够使用与 EF Core 类似的方法进行依赖注入工作(ASP.NET Core MVC) 项目。

在此先感谢您提供任何人可以提供的帮助!

PS 我觉得非常奇怪的是,互联网上没有任何关于 .NET Core、Azure Function Apps 和 EF Core 的更高版本的描述这种情况,这让我相信这可能是一个简单的错误。 希望不是。

也许一种解决方案是您可以尝试在您的函数中注入 IServiceProvider 而不是 AvastusContext ,就像我在下面的存储库类中注入的那样:

private readonly IServiceProvider serviceProvider;

        public SomeRepository(IServiceProvider serviceProvider)
        {
            this.serviceProvider = serviceProvider;
        }
    
        using var context = this.serviceProvider.GetService<XYZDBContext>(); 

这将为您提供一个上下文对象。 另外,不确定为什么要直接访问函数中的上下文以获得良好的实践,定义了一个上下文类,并维护存储库以在代码中执行任何 CRUD 操作。

Startup.cs 你可以添加额外的配置,比如:

builder.Services.AddDbContext<XYZDBContext>(
            options =>
            {
                options.UseSqlServer(
                    conn,
                    sqlServerOptionsAction:
                    sqlOptions =>
                    {
                        sqlOptions.EnableRetryOnFailure(maxRetryCount: 3, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
                    });
            }, ServiceLifetime.Transient);

这个配置在我当前的解决方案中工作得很好。 试试这个。

函数应用程序无法解析函数中的 dbcontext,因为它只能解析 BindingContext。 您需要创建自定义绑定以直接在函数应用中使用 dbcontext。

通过 DI 注入 dbcontext 的其他方法是将其传递给构造函数并在函数中使用类级别变量。

public class ParseThings
{
    private AvastusContext _context;
    public ParseThings(AvastusContext context){
        _context = context;
    }

    [FunctionName("ParseThings")]
    public void Run([BlobTrigger("summaries/{name}", Connection = "StorageConnectionString")]Stream myBlob, string name, ILogger log){
      // use _context here
    }
}

如果仍然无法解决,您可能需要查看是否正确配置了 functionsStartup

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM