我正在构建一个将持续运行的 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
