我们通过与IExtensionConfigProvider的参数绑定在Azure函数(netstandard20上的v2)中使用依赖项注入。将Microsoft.NET.Sdk.Functions从1.0.13升级到1.0.19(这将Microsoft.Azure.Webjobs.Host强制升级到v3)后,此功能不再起作用。我再也无法在IExtensionConfigProvider.Initialize函数中遇到断点了。对于具有目标框架net462的示例项目,使用相同功能版本的SDK可以很好地使用Microsoft.Azure.WebJobs v2。
这是运行时给出的错误:
错误索引方法“ Function1.Run”。 Microsoft.Azure.WebJobs.Host: 无法将参数'customThing'绑定为CustomType类型。确保 绑定支持参数类型。
这是示例应用程序的代码:
public static class Function1
{
[FunctionName("ThisFunction")]
public static async Task Run(
[TimerTrigger("0 */1 * * * *")]TimerInfo timer,
[Inject(typeof(CustomType))] CustomType customThing,
ExecutionContext context)
{
Console.WriteLine(customThing.GetMessage());
}
}
public class CustomType
{
public string GetMessage() => "Hi";
}
[Binding]
[AttributeUsage(AttributeTargets.Parameter)]
public class InjectAttribute : Attribute
{
public Type Type { get; }
public InjectAttribute(Type type) => Type = type;
}
public class InjectConfiguration : IExtensionConfigProvider
{
private IServiceProvider _serviceProvider;
public void Initialize(ExtensionConfigContext context)
{
var services = new ServiceCollection();
services.AddSingleton<CustomType>();
_serviceProvider = services.BuildServiceProvider(true);
context
.AddBindingRule<InjectAttribute>()
.BindToInput<dynamic>(i => _serviceProvider.GetRequiredService(i.Type));
}
}
答案 0 :(得分:9)
随着v3中对DI所做的更改以及扩展模型以创建扩展( IExtensionConfigProvider 实现是扩展),现在您首先需要使用 [assembly :WebJobsStartup] 程序集属性,并实现 IWebJobsStartup 接口。您可以在其中通过 builder.Services 将自己的服务添加到构建器,并注册扩展程序的配置提供程序类:
[assembly: WebJobsStartup(typeof(WebJobsExtensionStartup ), "A Web Jobs Extension Sample")]
namespace ExtensionSample
{
public class WebJobsExtensionStartup : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder)
{
//Don't need to create a new service collection just use the built-in one
builder.Services.AddSingleton<CustomType>();
//Registering an extension
builder.AddExtension<InjectConfiguration>();
}
}
}
然后在您的 IExtensionConfigProvider 中,您可以通过构造函数注入来注入任何依赖项,例如,绑定,绑定提供程序或任何其他自定义依赖项。就您而言,您只需获取对内置 IServiceProvider 的引用:
public class InjectConfiguration : IExtensionConfigProvider
{
private IServiceProvider _serviceProvider;
public InjectConfiguration(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public void Initialize(ExtensionConfigContext context)
{
context
.AddBindingRule<InjectAttribute>()
.BindToInput<dynamic>(i => _serviceProvider.GetRequiredService(i.Type));
}
}
要让主机加载扩展,必须通过func extensions install命令在JavaScript或Java函数的 bin / extensions.json 文件中注册该主机。在C#中, SDK 1.0.19 在当前函数项目或任何依赖项( ProjectReference 或 PackageReference ),并生成相应的extensions.json文件。