Dependency Injection (DI) has been available in .NET Core Web Applications for a while and now seems to have finally made it’s way to Azure Functions as well and is available in the current Azure Functions Runtime 2.0.12382. The GitHub issue tracking DI implementation in Azure Functions is here.

I’ve created a test project in an effort to figure out how it works but happily it seems pretty similar to using it in a Web Application.

In my case I wanted to inject a Serilog logger and a service to help in accessing the JSONPlaceholder API.

The first step is to add a new Startup.cs class to the project that inherits from IWebJobsStartup, this will allow you to added the required DI services and build the ServiceProvider.

Startup.cs

namespace JsonPlaceHolderDependencyInjection
{
    public class Startup : IWebJobsStartup
    {
        public Startup()
        {
            // Initialize serilog logger
            Log.Logger = new LoggerConfiguration()
                     .WriteTo.Console(Serilog.Events.LogEventLevel.Debug)
                     .MinimumLevel.Debug()
                     .Enrich.FromLogContext()
                     .CreateLogger();
        }

        public void Configure(IWebJobsBuilder builder)
        {
            ConfigureServices(builder.Services).BuildServiceProvider(true);
        }

        private IServiceCollection ConfigureServices(IServiceCollection services)
        {
            services
                .AddLogging(loggingBuilder =>
                    loggingBuilder.AddSerilog(dispose: true)
                )
                .AddTransient<IJsonPlaceholderClient, JsonPlaceholderClient>(client =>
                    new JsonPlaceholderClient(Environment.GetEnvironmentVariable("BaseAddress"))
                )
                .AddTransient<IJsonPlaceholderService, JsonPlaceholderService>();

            return services;
        }
    }
}

In your function you then need to provide an assembly reference to the Startup class [assembly: WebJobsStartup(typeof(Startup))] and you can then use DI as expected.

GetAlbums.cs

[assembly: WebJobsStartup(typeof(Startup))]

namespace JsonPlaceHolderDependencyInjection.Function
{
    public class GetAlbums
    {
        private readonly IJsonPlaceholderService _jsonPlaceholderService;
        private readonly ILogger _logger;

        public GetAlbums(IJsonPlaceholderService jsonPlaceholderService, ILoggerFactory loggerFactory)
        {
            _jsonPlaceholderService = jsonPlaceholderService;
            _logger = loggerFactory.CreateLogger("GetAlbums");
        }

        [FunctionName("GetAlbums")]
        public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", Route = "GetAlbums/{id?}")] HttpRequest req, int? id)
        {
            _logger.LogInformation("C# HTTP trigger function processed a request.");
            //log.LogInformation("C# HTTP trigger function processed a request.");

            if (id == null)
            {
                return (ActionResult)new OkObjectResult(await _jsonPlaceholderService.GetAlbums());
            }
            else
            {
                return (ActionResult)new OkObjectResult(await _jsonPlaceholderService.GetAlbumById((int)id));
            }
        }
    }
}

Leave a Reply

Your e-mail address will not be published. Required fields are marked *