使用 NoAutomaticTrigger 时 Azure WebJobs SDK 中的依赖注入?

Dependency Injection in Azure WebJobs SDK when using NoAutomaticTrigger?

我正在构建一个持续 运行 的 Azure WebJob。我希望 WebJob 使用与 ASP.NET Core 相同的 DI 样式。我在使用 NoAutomaticTrigger 配置连续 运行ning Web 作业时找到了这个答案 () on how to get DI/IoC working by using a custom IJobActivator. I also found this answer (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>();

问题在于,如果界面上有 NoAutomaticTrigger 属性,SDK 就会崩溃。解决办法是给class加上属性,然后把class注册为自己。

serviceCollection.AddSingleton<Application>();

进行更改后,答案中的解决方案效果很好。

AFAIK,NoAutomaticTrigger 属性在两种情况下很有用: 带触发器的函数防止自动调用触发器,允许手动轮询。没有其他属性的功能 将功能标记为可用的工作功能。在这两种情况下,标有此属性的函数永远不会被 JobHost 自动调用(在 RunAndBlock 期间)。相反,它们必须使用 Call 方法手动调用。而且,这个属性也可以用在非静态方法中。

这里有一些关于使用Azure WebJobs和Dependency Injection的相关文章,你可以参考: http://www.ryansouthgate.com/2016/05/10/azure-webjobs-and-dependency-injection/http://www.jerriepelser.com/blog/using-autofac-and-common-service-locator-with-azure-webjobs

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

示例程序class:

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();

    }
}

示例函数 class:

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