Say "Dependency Injection" one more time I DARE YOU

How to inject EF Core DbContext in an Azure Function

This post was most recently updated on September 25th, 2021.

3 min read.

Ah, one more on the related topics of different configurations for your Azure Function apps.

In this article, I will describe how you can configure the Entity Framework Core database context to be injected into your Azure Functions App. In my experience, this is a very typical and often-needed model to structure your Azure Functions. Therefore, while tooling and templates aren’t quite there, it’s worthwhile to document how to do this somewhere – well, here.

Solution

I’ve posted before about how to instantiate a database context using DbContextOptionsBuilder – see a copy-pasteable example right here: How to access EF’s DbContext in an Azure Function

However, if you want to use Dependency Injection (DI) instead, the implementation is just a bit different. Below, I’ll show you how!

Time needed: 10 minutes

How to configure injecting a DbContext in an Azure Function?

  1. Add a Startup class (WebJobsStartUp -attribute) to your Azure Function

    The steps to achieve this are described in this earlier blog post, so I’m not repeating them here:

    How to configure Azure Function’s startup?

  2. In the Startup, configure your DbContext like this:


    builder.Services.AddDbContext(options1 =>
    {
    options1.UseLazyLoadingProxies(false);
    options1.UseSqlServer(
    config["ConnectionStrings:DefaultConnection"],
    builder =>
    {
    builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
    builder.CommandTimeout(10);
    }
    );
    });


    The configuration options are only shown as an example – not required.

  3. Configure the database context to support being instantiated with options

    Now, you need to add a constructor to your database context class, like below:
    public ApplicationDbContext(DbContextOptions options) : base(options) { }
    Don’t worry about it being empty. EF Core figures out all the details, it just needs a method to work with :)

    If you skip this step, you might run into an error like the below:

    Microsoft.EntityFrameworkCore: AddDbContext was called with configuration, but the context type ‘ApplicationDbContext’ only declares a parameterless constructor. This means that the configuration passed to AddDbContext will never be used.

    If the configuration is passed to AddDbContext, then ‘ApplicationDbContext’ should declare a constructor that accepts a DbContextOptions and must pass it to the base constructor for DbContext.

    Value cannot be null. (Parameter ‘provider’)

  4. Configure the DbContext to be injected into your Azure Functions

    This is pretty nifty – since the database context is injected in your app as a service, you can just configure it to be injected at class initialization, directly in the constructor:

    private readonly ApplicationDbContext _applicationDbContext;

    public Function1 (ApplicationDbContext applicationDbContext) {
    _applicationDbContext = applicationDbContext;
    }


    You’ll need using -statements somewhat like these:
    Adding your Data Layer namespace (or project) as an import in your Azure Function.
    (“DataLayer” in the example above is the namespace my database context is in!)

  5. Use the database context in your function!

    Now it’s safe to use your database context in your code. No need to dispose of it – it’s tied to your Azure Function App’s lifecycle:

    if (!string.IsNullOrEmpty(name))
    {
    _applicationDbContext.Entities.Add(
    new DataLayer.Entities.Entity()
    {
    Name = name,
    Description = "Created in the Azure Function"
    }
    );
    }
    _applicationDbContext.SaveChanges();


And that’s all!

The whole thing looks somewhat like in the screenshot below:

A sample Azure Function injecting an Entity Framework Core database context.
A sample Azure Function injecting an Entity Framework Core database context.

Caveats

Note, that there’s a bit of a caveat in here regarding the lifecycle management of your injected objects. Namely, in case you created your function as static, you might need to refactor your code a bit as static functions can’t access instance objects.

An object reference is required for the non-static field, method or property when trying to access your database context - a bit of refactoring required!
An object reference is required for the non-static field, method, or property when trying to access your database context – a bit of refactoring is required!

Sample project

If you want a full-on working project template, you can grab one from this template directory – I contributed it there for your convenience!

https://github.com/dodyg/practical-aspnetcore/tree/3.1-LTS/projects/azure-functions/DbContextExample

Further reading

I’ve posted an article about a closely related case earlier – although in that case, I built the Database Context using DbContextOptionsBuilder. See that copy-pasteable example right here:

https://www.koskila.net/how-to-access-efs-dbcontext-in-an-azure-function-on-v2-runtime/

mm
4.8 5 votes
Article Rating
Subscribe
Notify of
guest

2 Comments
most voted
newest oldest
Inline Feedbacks
View all comments