Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I mix custom parameter binding with dependency injection in Azure Functions?

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.).

like image 697
Merrion Avatar asked Jan 25 '23 22:01

Merrion


2 Answers

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

        }
 }
like image 130
Rodrilink Avatar answered Jan 29 '23 21:01

Rodrilink


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");
        }        
    }   
}
like image 33
Napoleon Ike Jones Avatar answered Jan 29 '23 21:01

Napoleon Ike Jones