You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET6 Azure Function无法注入同解决方案其他项目依赖的问题

.NET6 Azure Function 跨项目依赖注入失败问题

问题场景

开发基于.NET6的Azure Function时,无法注入同一解决方案中其他项目的依赖,已尝试两种方案均失败:

方案1:使用FunctionsStartup配置DI

创建继承FunctionsStartup的Startup类进行依赖注入,代码如下:

[assembly: FunctionsStartup(typeof(Test.AzureFunctions.Startup))]

namespace Test.AzureFunctions
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder2) {
            builder2.Services.AddScoped<IMapperUnitOfWorkFactory, MapperUnitOfWorkFactory>();
            builder2.Services.AddScoped<IEntityOpsApiClient, EntityOpsApiClient>();
        }
    }
}

但执行using var unitOfWork = _unitOfWorkFactory.Create();时抛出异常,核心原因是系统无法解析MapperUnitOfWorkFactory自身的构造函数依赖。

方案2:改为控制台应用并添加Program.cs

将Azure Function项目的输出类型从类库改为控制台应用,添加Program.cs文件,但运行时该文件从未被执行。

函数代码示例

TestFunction1类代码:

namespace Test.AzureFunctions.Functions
{
    public class TestFunction1
    {
        private readonly IMapperUnitOfWorkFactory _unitOfWorkFactory;
        private readonly IEntityOpsApiClient _entityOpsApiClient;

        public TestFunction1(
            IMapperUnitOfWorkFactory unitOfWorkFactory, 
            IEntityOpsApiClient entityOpsApiClient) {
            _unitOfWorkFactory = unitOfWorkFactory.ThrowIfNull(nameof(unitOfWorkFactory));
            _entityOpsApiClient = entityOpsApiClient;
        }

        [FunctionName("TestFunction1")]
        public void Run([TimerTrigger("0 * * * * *")] TimerInfo myTimer, ILogger log)
        {
            log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
            var exceptions = new List<Exception>();          
            using var unitOfWork = _unitOfWorkFactory.Create();
            var client = unitOfWork.ClientRepository.GetFirstOrDefaultAsync(c => c.ClientId == 1).Result;
        }
    }
}

报错行:using var unitOfWork = _unitOfWorkFactory.Create();

解决方案

1. 补全MapperUnitOfWorkFactory的所有依赖注册

异常的核心是MapperUnitOfWorkFactory自身的构造函数依赖未被注入到DI容器中。检查该类的构造函数,把所有参数对应的服务一并注册:

public override void Configure(IFunctionsHostBuilder builder) 
{
    // 示例:注册MapperUnitOfWorkFactory依赖的DbContext
    builder.Services.AddDbContext<YourDbContext>(options => 
        options.UseSqlServer(Environment.GetEnvironmentVariable("ConnectionString")));
    
    // 注册自定义服务
    builder.Services.AddScoped<IMapperUnitOfWorkFactory, MapperUnitOfWorkFactory>();
    builder.Services.AddScoped<IEntityOpsApiClient, EntityOpsApiClient>();
}

2. 验证FunctionsStartup配置正确性

  • 确保程序集特性[assembly: FunctionsStartup(...)]的类型指向正确,命名空间不要写错。
  • 确认项目已安装Microsoft.Azure.Functions.Extensions NuGet包,这是使用FunctionsStartup的必要依赖。

3. 正确配置隔离模式下的Program.cs

如果要使用控制台应用模式(隔离模式),需严格遵循以下配置:

  • 项目输出类型设为控制台应用,安装Microsoft.Azure.Functions.Worker和Microsoft.Azure.Functions.Worker.Sdk NuGet包。
  • Program.cs代码需符合隔离模式启动规范:
var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services => 
    {
        services.AddScoped<IMapperUnitOfWorkFactory, MapperUnitOfWorkFactory>();
        services.AddScoped<IEntityOpsApiClient, EntityOpsApiClient>();
        // 注册所有依赖项
    })
    .Build();

host.Run();
  • 检查项目文件(.csproj)配置:
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
    <OutputType>Exe</OutputType>
    <_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.14.1" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.10.0" />
    <!-- 对应触发器的包,比如TimerTrigger -->
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Timer" Version="4.1.0" />
  </ItemGroup>
</Project>

注意:隔离模式下的触发器特性需使用Microsoft.Azure.Functions.Worker.Extensions命名空间下的版本,而非旧的Microsoft.Azure.WebJobs.Extensions。

4. 检查跨项目引用有效性

  • 确保Azure Function项目已添加对依赖项目的项目引用(而非文件引用)。
  • 确认依赖项目能正常编译,其输出DLL已被复制到Azure Function项目的输出目录。

5. 捕获完整异常信息排查问题

在函数中添加异常捕获,输出内部异常详情,明确未注册的依赖项:

[FunctionName("TestFunction1")]
public void Run([TimerTrigger("0 * * * * *")] TimerInfo myTimer, ILogger log)
{
    log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
    try
    {
        using var unitOfWork = _unitOfWorkFactory.Create();
        var client = unitOfWork.ClientRepository.GetFirstOrDefaultAsync(c => c.ClientId == 1).Result;
    }
    catch (Exception ex)
    {
        log.LogError(ex, "创建UnitOfWork失败");
        // 输出所有内部异常
        var innerEx = ex.InnerException;
        while (innerEx != null)
        {
            log.LogError(innerEx, "内部异常");
            innerEx = innerEx.InnerException;
        }
    }
}

内容的提问来源于stack exchange,提问作者Neha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 08:33:22