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

在Azure Logic Apps自定义代码中实现依赖注入的问题求助

.NET 8孤立模式Logic Apps自定义函数依赖注入配置方案

问题背景

通过VS Code创建包含自定义.NET 8孤立模式Azure Function的Azure Logic Apps工作区,函数可在工作流中正常运行,但无法配置依赖注入:

  • 常规孤立模式Function通过Program.cs配置宿主,但项目中无此文件
  • 尝试创建进程模式适用的Startup.cs无效
  • 推测宿主构建流程被封装在Microsoft.Azure.Workflows.Functions.CustomCodeNetFxWorker.exe进程中,当前仅ILoggerFactory已注册

重现步骤

  • 打开已安装Azure Logic Apps、Azurite扩展的Visual Studio Code
  • 在Azure扩展中创建Azure Logic Apps工作区
  • 选择带自定义项目的Logic Apps,其余保持默认值
  • 项目仅包含示例函数(代码如下):
namespace My.Fun
{
    using System;
    using System.Threading.Tasks;
    using Microsoft.Azure.Functions.Extensions.Workflows;
    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Extensions.Logging;

    /// <summary>
    /// Represents the function flow invoked function.
    /// </summary>
    public class function
    {
        private readonly ILogger<function> logger;

        public function(ILoggerFactory loggerFactory)
        {
            logger = loggerFactory.CreateLogger<function>();
        }

        /// <summary>
        /// Executes the logic app workflow.
        /// </summary>
        /// <param name="zipCode">The zip code.</param>
        /// <param name="temperatureScale">The temperature scale (e.g., Celsius or Fahrenheit).</param>
        [Function("function")]
        public Task<Weather> Run([WorkflowActionTrigger] int zipCode, string temperatureScale)
        {
            this.logger.LogInformation("Starting function with Zip Code: " + zipCode + " and Scale: " + temperatureScale);

            // Generate random temperature within a range based on the temperature scale
            Random rnd = new Random();
            var currentTemp = temperatureScale == "Celsius" ? rnd.Next(1, 30) : rnd.Next(40, 90);
            var lowTemp = currentTemp - 10;
            var highTemp = currentTemp + 10;

            // Create a Weather object with the temperature information
            var weather = new Weather()
            {
                ZipCode = zipCode,
                CurrentWeather = $"The current weather is {currentTemp} {temperatureScale}",
                DayLow = $"The low for the day is {lowTemp} {temperatureScale}",
                DayHigh = $"The high for the day is {highTemp} {temperatureScale}"
            };

            return Task.FromResult(weather);
        }
    }

    public class Weather
    {
        public int ZipCode { get; set; }
        public string CurrentWeather { get; set; }
        public string DayLow { get; set; }
        public string DayHigh { get; set; }
    }
}
  • 可观察到ILogger已注册可用,但无Startup.cs或Program.cs用于扩展服务集合

解决方案

步骤1:创建宿主启动扩展类

实现IFunctionsWorkerApplicationBuilderStartup接口,并通过程序集级别属性标记,让宿主启动时自动加载该扩展:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;

// 程序集级别标记,指定启动扩展类
[assembly: FunctionsWorkerApplicationBuilderStartup(typeof(My.Fun.WorkerStartup))]

namespace My.Fun
{
    public class WorkerStartup : IFunctionsWorkerApplicationBuilderStartup
    {
        public void Configure(FunctionsWorkerApplicationBuilder builder)
        {
            // 在此注册你的依赖服务,示例:
            // 注册Scoped服务(每次函数执行创建实例)
            builder.Services.AddScoped<IMyService, MyService>();
            // 注册Singleton服务(全局唯一实例)
            // builder.Services.AddSingleton<IMySingletonService, MySingletonService>();
        }
    }

    // 示例服务接口与实现
    public interface IMyService
    {
        string GetServiceMessage();
    }

    public class MyService : IMyService
    {
        public string GetServiceMessage()
        {
            return "来自自定义依赖服务的消息";
        }
    }
}

步骤2:在函数类中注入依赖

修改函数类的构造函数,直接注入已注册的服务:

namespace My.Fun
{
    using System;
    using System.Threading.Tasks;
    using Microsoft.Azure.Functions.Extensions.Workflows;
    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Extensions.Logging;

    public class function
    {
        private readonly ILogger<function> _logger;
        private readonly IMyService _myService;

        // 构造函数注入ILoggerFactory和自定义服务
        public function(ILoggerFactory loggerFactory, IMyService myService)
        {
            _logger = loggerFactory.CreateLogger<function>();
            _myService = myService;
        }

        [Function("function")]
        public Task<Weather> Run([WorkflowActionTrigger] int zipCode, string temperatureScale)
        {
            this._logger.LogInformation("Starting function with Zip Code: " + zipCode + " and Scale: " + temperatureScale);
            // 使用自定义服务
            this._logger.LogInformation(_myService.GetServiceMessage());

            // 原有业务逻辑...
            Random rnd = new Random();
            var currentTemp = temperatureScale == "Celsius" ? rnd.Next(1, 30) : rnd.Next(40, 90);
            var lowTemp = currentTemp - 10;
            var highTemp = currentTemp + 10;

            var weather = new Weather()
            {
                ZipCode = zipCode,
                CurrentWeather = $"The current weather is {currentTemp} {temperatureScale}",
                DayLow = $"The low for the day is {lowTemp} {temperatureScale}",
                DayHigh = $"The high for the day is {highTemp} {temperatureScale}"
            };

            return Task.FromResult(weather);
        }
    }
}

原理说明

Logic Apps的自定义函数宿主虽被封装,但仍支持通过IFunctionsWorkerApplicationBuilderStartup接口扩展服务集合。程序集级别的FunctionsWorkerApplicationBuilderStartup属性会告诉宿主在启动时执行指定类的Configure方法,从而完成依赖服务的注册。

注意事项

  • 服务生命周期选择:根据函数执行模型,推荐使用Scoped生命周期(每次函数执行创建新实例),Singleton适用于全局共享的服务
  • 确保项目已引用必要的NuGet包:Microsoft.Azure.Functions.Worker、Microsoft.Azure.Functions.Worker.Extensions.Workflows(默认创建项目已包含)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 04:05:14