2

I am trying to pass my local configurations within my azure functions into an iServiceCollection in another project with which this function has dependency.

I am working in .NET 6

Here is my function startup.cs based on the answer to this question

[assembly: FunctionsStartup(typeof(DatabaseInit.Startup))]
namespace Edos.DatabaseInit;
public class Startup:FunctionsStartup
{


    public override void Configure(IFunctionsHostBuilder builder)
    {
        var configuration = builder.GetContext().Configuration;
       
        builder.Services.AddInfrastructure(configuration);
       
    }

}

And this is my local.settings.json

{
  "IsEncrypted": false,
  "ServiceBusConnectionString": "myconnectionstring",
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet"
  }
}

My function

public class CosmosInit
{
    private readonly IMessagingService _messagingService;


    public CosmosInit(IMessagingService messagingService)
    {
        _messagingService = messagingService;
        
    }
    [FunctionName("CosmosInit")]
    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
        ILogger log)
    {

        await _messagingService.PushToTopic("demotopic", "message");

        return new OkObjectResult(responseMessage);
    }
}

Here is the Above AddInfrastructure method in my dependency project of my Azure function

public static class DependencyInjection
{
    public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
    { 
        var serviceBusConnectionString = Environment.GetEnvironmentVariable("ServiceBusConnectionString");
        if (string.IsNullOrEmpty(serviceBusConnectionString))
        {
            throw new InvalidOperationException(
                "Please specify a valid ServiceBusConnectionString in the Azure Functions Settings or your local.settings.json file.");
        }

        //using AMQP as transport
        services.AddSingleton((s) => {
            return new ServiceBusClient(serviceBusConnectionString, new ServiceBusClientOptions() { TransportType = ServiceBusTransportType.AmqpWebSockets });
        });
        services.AddScoped<IMessagingService, MessagingService>();

        return services;
    }
}

And this is where my method (Within the infrastructure project)

public class MessagingService: IMessagingService
{
    private readonly ServiceBusClient _serviceBusClient;

    public MessagingService(ServiceBusClient serviceBusClient)
    {
        _serviceBusClient = serviceBusClient;
    }
    // the sender used to publish messages to the topic
    
    public async Task<int> PushToTopic(string topic, string serviceMessage)
    {
        var sender = _serviceBusClient.CreateSender(topic);
        var message = new ServiceBusMessage(serviceMessage);
        await sender.SendMessageAsync(message);
        return 1;

    }
}

But when executing there is no error. But within the infrastructure project Environment.GetEnvironmentVariable("ServiceBusConnectionString") just shows as null. And I found no configurations its taking from the functions local.settings.json

Please suggest what I did wrong or how can I fix this.. please

Sandeep Thomas
  • 4,303
  • 14
  • 61
  • 132
  • If you send your configuration as parameter, why you try to read as Enviroment variable? Try using "configuration" inside your method AddInfrastructure and read it with "GetSection" – Mate May 18 '22 at 02:38
  • @Mate I tried this way in my infrastructure project var serviceBusConnectionString = configuration.GetSection("ServiceBusConnectionString").Value; which is also null – Sandeep Thomas May 18 '22 at 03:03
  • please, do the same in Startup:FunctionsStartup , method Configure. To verify if it's loading your local.settings.json. – Mate May 18 '22 at 03:14
  • Thanks a lot Mate.. I just tried that and it returning null var configuration = builder.GetContext().Configuration; var s = configuration.GetValue("ServiceBusConnectionString"); So is it because the way I am initializing the configuration?? So could you please suggest how can I pass the configuration into my infrastructure project. – Sandeep Thomas May 18 '22 at 03:20

1 Answers1

1

Based on the comments, try to find or add a code like

using Microsoft.Extensions.Configuration;

 Some class {

    ...
        var builder = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("local.settings.json", optional: false)
        .Build();

        //just to verify
        var conn = builder.GetSection("ServiceBusConnectionString").Get<string>();
        Console.WriteLine(conn);
     ...
}

You could add it to your current method "Configure" , and keep the rest of your code as is. Or verify if you have a previous point where the configuration is loaded.

By default, configuration files such as appsettings.json are not automatically copied to the function app's output folder. Update your .csproj file to match the following sample to ensure the files are copied.

From: https://learn.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection

 Some class {

    ...
        var builder = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("local.settings.json", optional: false)
        .AddEnvironmentVariables() //HERE!!

        //just to verify
        var conn = Environment.GetEnvironmentVariable("ServiceBusConnectionString");
        Console.WriteLine(conn);
     ...
}
Mate
  • 4,976
  • 2
  • 32
  • 38
  • Thanks a lot Mate. I followed it and it simply does the job.. :) But one question, this will work fine for local.settings.json. But how come it work for taking values from Environment variables when deployed to azure?? – Sandeep Thomas May 18 '22 at 04:04
  • Great! check the link and the update. You need to call " .AddEnvironmentVariables();" – Mate May 18 '22 at 04:07
  • 1
    Thats awesome.. Thats a lot man.. Btw I am wondering things getting complicated when new version comes which was easy in older versions of .net or I could be interpreting it wrong.. ;) – Sandeep Thomas May 18 '22 at 04:10
  • Embrace it. Change is the new normal. – Mate May 18 '22 at 04:12