I have an Azure Functions app that uses custom parameter bindings that were initialised in the [WebJobsStartup] - how do I migrate these to the new [FunctionsStartup] way of doing things?
In the [WebJobsStartup] the bindings were registered by the call to builder.AddExtension with .AddBindingRule
Now the new Azure SDK says to use [FunctionsStartup] - how do I hook in (or replace) .AddBindingRule in this?
The FunctionsStartup implementation looks like:-
[assembly: FunctionsStartup(typeof(EventSourcingOnAzureFunctions.Common.Startup))]
namespace EventSourcingOnAzureFunctions.Common
{
public class Startup
: FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.AddAppSettingsToConfiguration();
// Initialise any common services
CQRSAzureBindings.InitializeServices(builder.Services);
builder.Services.AddWebJobs(ConfigureWebJobs );
}
public void ConfigureWebJobs(JobHostOptions hostOptions)
{
}
}
And the way it used to register the binding rules is like:-
/// <summary>
/// Initailise any common dependency injection configuration settings
/// </summary>
/// <param name="context"></param>
public static void InitializeInjectionConfiguration(ExtensionConfigContext context)
{
// Set up the dependency injection stuff for the custom bindings
// 1: EventStream
context
.AddBindingRule<EventStreamAttribute>()
.BindToInput<EventStream>(BuildEventStreamFromAttribute)
;
}
If I run the function app as is the binding rules code does not get called and as a result the function indexing fails with e.g.
Microsoft.Azure.WebJobs.Host: Error indexing method 'DepositMoney'. Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'bankAccountEvents' to type EventStream. Make sure the parameter Type is supported by the binding. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.).
You can get an instance of [WebJobsStartup] to call builder.AddExtension in your Startup.cs
In my case, I need to use an extension from a NuGet package
using Microsoft.Azure.WebJobs.Extensions.Kafka;
But I passed through the same case as you, but finally, I made it work :)
[assembly:
FunctionsStartup(typeof(EventSourcingOnAzureFunctions.Common.Startup))]
namespace EventSourcingOnAzureFunctions.Common
{
public class Startup
: FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
var serviceProvider = builders.Services.BuildServiceProvider();
var env = serviceProvider.GetRequiredService<IHostEnvironment>();
var appDirectory = serviceProvider.GetRequiredService<IOptions<ExecutionContextOptions>>().Value.AppDirectory;
// IWebJobsBuilders instance
var wbBuilder = builder.Services.AddWebJobs(x => { return; });
wbBuilder.AddKafka();
// And now you can use AddExtension
// wbBuilder.AddExtension
}
}
To do this you would have two separate startup classes. One that inherits from FunctionsStartup and the other that implements the IWebJobsStartup interface. The WebJobsStartup runs first, then the FunctionsStartup.
Here's how I tested it.
WebJobsStartup class
namespace CustomBinding
{
public class WebJobsStartup : IWebJobsStartup
{
void IWebJobsStartup.Configure(IWebJobsBuilder builder)
{
Debug.WriteLine("WebJobsStartup.Configure");
}
}
}
AssemblyInfo class
using Microsoft.Azure.WebJobs.Hosting;
[assembly: WebJobsStartup(typeof(CustomBinding.WebJobsStartup))]
Startup Class
[assembly: FunctionsStartup(typeof(CustomBinding.Startup))]
namespace CustomBinding
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
Debug.WriteLine("FunctionsStartup.Configure");
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With