Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception when using ConfigurationBuilder with Durable Functions #2059

Open
coreConvention opened this issue Dec 14, 2018 · 5 comments
Open

Comments

@coreConvention
Copy link

This seems like such an odd error, and it may not be a bug. But was hindering something I was trying to do with IServicesCollection so I was hoping someone might know whats going on. I am attempting to use a ServiceBusTrigger with a Durable function. I am using an implementation of IWebJobsStartup to do my registrations. I had originally approached this the same way I do with normal functions; I instantiate an instance of ConfigurationBuilder in the configure method of my IWebJobsStartup implementation and pass my config instance to a function where I register all my services.

public void Configure(IWebJobsBuilder builder)
{
    var config = new ConfigurationBuilder()
        .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
        .AddEnvironmentVariables()
        .Build();
    RegisterServices(builder.Services, config);
    builder.AddExtension<InjectConfiguration>();
}

One registration in particular requires the ConfigurationBuilder to resolve connection string through an instance of IConfiguration:

services.AddSingleton<IContextProvider<ValidationContext>>(sp =>
{
    return new ContextProvider<ValidationContext>(config.GetValue<string>("ContextConnectionString"));
});

This worked great with normal functions but a couple weird things happen with durable functions. The first was an error:

Microsoft.Azure.WebJobs.ServiceBus: Method not found: 'Microsoft.Azure.WebJobs.IWebJobsExtensionBuilder Microsoft.Azure.WebJobs.WebJobsExtensionBuilderExtensions.ConfigureOptions(Microsoft.Azure.WebJobs.IWebJobsExtensionBuilder, System.Action`3<Microsoft.Extensions.Configuration.IConfiguration,System.String,!!0>)'.

Which oddly enough seemed to happen even if I wasn't using the instance of configurationbuilder anywhere. Its very existance seems to cause this error. Even just having "var config = new ConfigurationBuilder().Build();" in there but not using it would cause this error. Deleting it resolves that issue. Weird. This happens when it calls builder.AddServiceBus(p => { }) in ServiceBusWebJobsBuilderExtensions.cs in the service bus extensions. The stack trace is at the bottom of this issue.

I remove the var config = new ConfigurationBuilder()...Build(); stuff from IWebJobsStartup it just magically starts working. Again this happens whether I use "config" or not.

So anyway I removed that assuming maybe it was interfering with something in the service bus extensions, and tried to just resolve IConfiguration from the service provider in my registration:

services.AddSingleton<IContextProvider<ValidationContext>>(sp =>
{
    var config = sp.GetService<IConfiguration>();               
    return new ContextProvider<ValidationContext>(config.GetValue<string>("ContextConnectionString"));
});

...at which point I get an error saying it could not resolve IConfiguration. Doh! So I just removed the connection string from the constructor in ContextProvider and attempted to resolve IConfiguration instead, but it seems I cannot resolve IConfiguration from anywhere in the app either, even when the rest of it is working. Am I missing something here? How can I use IConfiguration in durable functions with IConfiguration?

Stack Trace:
   at Microsoft.Extensions.Hosting.ServiceBusHostBuilderExtensions.AddServiceBus(IWebJobsBuilder builder, Action`1 configure)
   at Microsoft.Extensions.Hosting.ServiceBusHostBuilderExtensions.AddServiceBus(IWebJobsBuilder builder) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Extensions.ServiceBus\Config\ServiceBusWebJobsBuilderExtensions.cs:line 23
   at Microsoft.Azure.WebJobs.ServiceBus.ServiceBusWebJobsStartup.Configure(IWebJobsBuilder builder) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Extensions.ServiceBus\ServiceBusWebJobsStartup.cs:line 16
   at Microsoft.Azure.WebJobs.WebJobsBuilderExtensions.UseWebJobsStartup(IWebJobsBuilder builder, Type startupType) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Hosting\WebJobsBuilderExtensions.cs:line 72
   at Microsoft.Azure.WebJobs.WebJobsBuilderExtensions.UseExternalStartup(IWebJobsBuilder builder, IWebJobsStartupTypeLocator startupTypeLocator) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Hosting\WebJobsBuilderExtensions.cs:line 103
   at Microsoft.Azure.WebJobs.Script.ScriptHostBuilderExtensions.UseScriptExternalStartup(IWebJobsBuilder builder, String rootScriptPath) in C:\azure-webjobs-sdk-script\src\WebJobs.Script\ScriptHostBuilderExtensions.cs:line 182
   at Microsoft.Azure.WebJobs.Script.ScriptHostBuilderExtensions.<>c__DisplayClass3_0.<AddScriptHostCore>b__0(IWebJobsBuilder webJobsBuilder) in C:\azure-webjobs-sdk-script\src\WebJobs.Script\ScriptHostBuilderExtensions.cs:line 107
   at Microsoft.Extensions.Hosting.WebJobsHostBuilderExtensions.<>c__DisplayClass2_0.<ConfigureWebJobs>b__1(HostBuilderContext context, IServiceCollection services) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Hosting\WebJobsHostBuilderExtensions.cs:line 37
   at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
   at Microsoft.Extensions.Hosting.HostBuilder.Build()
   at Microsoft.Azure.WebJobs.Script.WebHost.DefaultScriptHostBuilder.BuildHost(Boolean skipHostStartup, Boolean skipHostConfigurationParsing) in C:\azure-webjobs-sdk-script\src\WebJobs.Script.WebHost\DefaultScriptHostBuilder.cs:line 59
   at Microsoft.Azure.WebJobs.Script.WebHost.WebJobsScriptHostService.BuildHost(Boolean skipHostStartup, Boolean skipHostJsonConfiguration) in C:\azure-webjobs-sdk-script\src\WebJobs.Script.WebHost\WebJobsScriptHostService.cs:line 267
   at Microsoft.Azure.WebJobs.Script.WebHost.WebJobsScriptHostService.StartHostAsync(CancellationToken cancellationToken, Int32 attemptCount, JobHostStartupMode startupMode) in C:\azure-webjobs-sdk-script\src\WebJobs.Script.WebHost\WebJobsScriptHostService.cs:line 134
@coreConvention coreConvention changed the title Exception when using ConfigurationBuilder with Exception when using ConfigurationBuilder with Durable Functions Dec 14, 2018
@cgillum
Copy link
Contributor

cgillum commented Dec 14, 2018

I think this question belongs in the WebJobs SDK repo. @fabiocav would you mind transferring it over and taking a look? The GitHub issue transfer feature isn't allowing me to do so myself (it's not visible to me).

@coreConvention
Copy link
Author

@cgillum if you think thats where it needs to go great. However, I have only observed this behavior using durable functions. Everything seems to work as expected with the regular azure functions. shrugs

Anyhow, thanks for taking a look nonetheless!

@fabiocav fabiocav transferred this issue from Azure/azure-functions-durable-extension Dec 14, 2018
@coreConvention
Copy link
Author

I was able to get this sorted out. Turns out this fails when referencing any 2.2.0 versions of the Microsoft.Extensions.Configuration packages. Going back to 2.1.0 seems to fix the issue. Although even after that I had more issues with Microsoft.Extensions.Logging, because of a dependency on Microsoft.Extensions.DependecyInjection.Abstractions. In the end all of those related packages had to be downgraded to 2.1.0.

@alan-g-chen
Copy link

alan-g-chen commented Jan 10, 2019

Adding on to say - it looks like this happens with any package in the Microsoft.Extensions namespace. I started encountering a similar issue when adding the Microsoft.Extensions.Caching.Memory 2.2.0 package.

@codecat15
Copy link

@cgillum I am using version 3.1.0 of Microsoft.Extension and still getting the same issue, it seems that the configuration builder does have some crazy behavior with durable function. Given below is the code I am using, is there a workaround for this?

 private static AppSettings GetApplicationSettings()
        {
            var configBuilder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appSettings.json", optional: true, reloadOnChange: true).AddEnvironmentVariables().Build();

        var appSettings = new AppSettings();

        configBuilder.GetSection("AppSettings").Bind(appSettings);
        return appSettings;
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants