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

Dotnet 9 Functions IHostApplicationBuilder #3773

Open
cliedeman opened this issue Nov 20, 2024 · 5 comments
Open

Dotnet 9 Functions IHostApplicationBuilder #3773

cliedeman opened this issue Nov 20, 2024 · 5 comments

Comments

@cliedeman
Copy link

Problem Statement

Dotnet 9 has included support for using the IHostApplicationBuilder style for app creation

https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide?tabs=ihostapplicationbuilder%2Cwindows#start-up-and-configuration

With the new style we dont have access to the HostBuilderContext

var builder = FunctionsApplication.CreateBuilder(args);

builder.UseSentry(<missing>, options =>
{
    ...
});

Temporary workaround:

var builder = FunctionsApplication.CreateBuilder(args);

var context = new HostBuilderContext(new Dictionary<object, object>())
{
    Configuration = builder.Configuration,
};

builder.UseSentry(context, options =>
{
    ...
});

I see 2 obvious solutions:

Either add a builder extension with using FunctionsApplicationBuilder

or do a cast

    public static IHostApplicationBuilder UseSentry(
        this IFunctionsWorkerApplicationBuilder builder,
        Action<SentryAzureFunctionsOptions>? optionsConfiguration)
    {
        builder.UseMiddleware<SentryFunctionsWorkerMiddleware>();
        IServiceCollection services = builder.Services;
        IConfigurationSection section;
        if (builder is IHostApplicationBuilder applicationBuilder)
        {
            section = applicationBuilder.Configuration.GetSection("Sentry");
        }
        else
        {
            throw new ArgumentException("builder is not a IHostApplicationBuilder");
        }
        
        services.AddSingleton<IConfigureOptions<SentryAzureFunctionsOptions>>((Func<IServiceProvider, IConfigureOptions<SentryAzureFunctionsOptions>>) (_ => (IConfigureOptions<SentryAzureFunctionsOptions>) new SentryAzureFunctionsOptionsSetup((IConfiguration) section)));
        if (optionsConfiguration != null)
            services.Configure<SentryAzureFunctionsOptions>(optionsConfiguration);
        services.AddLogging();
        services.AddSingleton<ILoggerProvider, SentryAzureFunctionsLoggerProvider>();
        services.AddSingleton<IConfigureOptions<SentryAzureFunctionsOptions>, SentryAzureFunctionsOptionsSetup>();
        services.AddSentry<SentryAzureFunctionsOptions>();
        return builder;
    }

Solution Brainstorm

No response

@bruno-garcia
Copy link
Member

Thanks for raising this. We're working on improved .NET 9.0 support now on main branch as part of our 5.0.0 release.

Would you consider opening a PR?

@cliedeman
Copy link
Author

Sure. which approach should I use?

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 3 Nov 21, 2024
@bruno-garcia
Copy link
Member

Not sure tbqh. @jamescrosswell opinions?

If the type cast is safe, maybe that's the simplest as no new API needed

@jamescrosswell
Copy link
Collaborator

jamescrosswell commented Nov 21, 2024

It looks like it'd be easy to break with the cast option if someone called this incorrectly from an app that used the older IHostBuilder:

        else
        {
            throw new ArgumentException("builder is not a IHostApplicationBuilder");
        }

Ideally we wouldn't find out at runtime what we could prevent with static types.

SentryFunctionsWorkerApplicationBuilderExtensions doesn't actually need HostBuilderContext or an IHostApplicationBuilder... ultimately the dependency it's after is IConfiguration. I think it makes sense to have one overload (where the real work happens) that takes an IConfiguration parameter... and then wrap this with some other overloads that are built to work specifically with either HostBuilderContext or IHostApplicationBuilder.

@GetoXs
Copy link

GetoXs commented Nov 22, 2024

Hi guys,
How about change extension "base" interface from IFunctionsWorkerApplicationBuilder to IHostApplicationBuilder? It would simplify code, and it could be reusable in other sentry integrations (not only azure function).

	public static IHostApplicationBuilder UseSentry(
		this IHostApplicationBuilder builder,
		Action<SentryAzureFunctionsOptions>? optionsConfiguration)
	{

		var services = builder.Services;
		var section = builder.Configuration.GetSection("Sentry");
#if NET8_0_OR_GREATER
        services.AddSingleton<IConfigureOptions<SentryAzureFunctionsOptions>>(_ =>
            new SentryAzureFunctionsOptionsSetup(section)
        );
#else
        services.Configure<SentryAzureFunctionsOptions>(options =>
            section.Bind(options));
#endif
		...
	}

PS @cliedeman many thanks for workaround.

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 3 Nov 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Status: Waiting for: Product Owner
Development

No branches or pull requests

4 participants