Skip to main content
 首页 » 编程设计

c#之使用 NoAutomaticTrigger 时 Azure WebJobs SDK 中的依赖注入(inject)

2024年02月04日29yjmyzz

我正在构建一个将持续运行的 Azure WebJob。我希望 WebJob 使用与 ASP.NET Core 相同的 DI 样式。我找到了关于如何使用自定义 IJobActivator 使 DI/IoC 工作的答案 ( Dependency injection using Azure WebJobs SDK? )。我还找到了关于使用 NoAutomaticTrigger 配置持续运行的 Web 作业的答案 ( Azure WebJobs - No functions found - How do I make a trigger-less job?)。

问题在于 NoAutomaticTrigger 方法使用静态方法,这与 DI/IoC 不兼容。我认为这是因为没有什么会导致使用 NoAutomaticTrigger 方法的服务得到解析(如队列消息)。我觉得 ITypeLocator 可能是一条前进的道路,但这只是一种预感。

其他 NoAutomaticTrigger 示例中使用的 JobHost.Call 方法仅限于静态方法。我如何拥有通过 DI 解析的服务,该服务从 Program.cs 中的 JobHost(或其他一些方法)调用中解析和调用?


Iza Eddi-son Atsou 在下面建议的解决方案有效,但有一点不足。我习惯于通过服务上的界面注册我的服务。有点像

serviceCollection.AddSingleton<IApplication, Application>(); 

问题在于,如果接口(interface)上有 NoAutomaticTrigger 属性,SDK 就会崩溃。解决方案是将属性添加到类中,并将类注册为自身。

serviceCollection.AddSingleton<Application>(); 

一旦做出更改,答案中的解决方案就非常有效。

请您参考如下方法:

WebJobs SDK 现在支持触发实例方法,而不仅仅是静态方法。 NoAutomaticTrigger 方法不再需要是静态的。更新 SDK,使用您找到的自定义 IJobActivator 方法并记住注册您的 Functions 类,当然还有您的其他依赖项。

示例程序类:

class Program 
{ 
 
    static void Main() 
    { 
        var container = new UnityContainer(); 
 
        //the instance to be injected 
        var systemClient = new JobSystemClient 
        { 
            UserName = "admin", 
            PassWord = "admin1234" 
        }; 
 
        container.RegisterInstance<ISystemClient>(systemClient); 
 
        //Registration of the Functions class 
        container.RegisterType<Functions>();             
 
        var activator = new UnityJobActivator(container); 
 
        var config = new JobHostConfiguration(); 
        config.JobActivator = activator;             
 
        var host = new JobHost(config); 
        // The following code will invoke a function called ManualTrigger and  
        // pass in data (value in this case) to the function 
        host.Call(typeof(Functions).GetMethod("ManualTrigger"), new { value = 20 }); 
 
        host.RunAndBlock(); 
 
    } 
} 

示例函数类:

public class Functions 
{ 
    private readonly ISystemClient _systemClient; 
    public Functions(ISystemClient systemClient) 
    { 
        _systemClient = systemClient; 
    } 
 
    //Not static anymore 
    [NoAutomaticTrigger] 
    public void ManualTrigger(TextWriter log, int value, [Queue("queue")] out string message) 
    { 
        log.WriteLine("Function is invoked with value={0}", value); 
        message = value.ToString();          
        log.WriteLine("username:{0} and password:{1}", _systemClient.UserName, _systemClient.PassWord); 
    } 
} 

这是输出:

Found the following functions: 
TestWebJob.Functions.ManualTrigger 
Executing 'Functions.ManualTrigger' (Reason='This function was programmatically called via the host APIs.', Id=bf9aedc0-89d1-4ba0-a33e-9b23e0d7b8a2) 
Function is invoked with value=20 
Following message will be written on the Queue=20 
username:admin and password:admin1234 
Executed 'Functions.ManualTrigger' (Succeeded, Id=bf9aedc0-89d1-4ba0-a33e-9b23e0d7b8a2) 
Job host started