Sandeep Thomas
Sandeep Thomas

Reputation: 4747

Environment variables are null when injecting IConfiguration into service collection

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

Upvotes: 2

Views: 1331

Answers (1)

Mate
Mate

Reputation: 5274

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

Upvotes: 1

Related Questions