0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Distribute an Azure Function through a library

Last updated at Posted at 2022-12-18

Prerequisites

  • Visual studio with Azure Function enabled

Case

When maintaining multiple Azure Function projects, occasionally we need to duplicate some common-use functions between the projects that are not directly related to the main projects. For example health checks or sending system info messages to a queue. To reduce the duplication and maintenance, we can actually create a Function inside library which will run inside all Azure Function projects which references it.

d1.png

In this article, I created a brief solution with two Azure Function projects. The content inside those functions can be unrelated to each other, but on each project we need to have an ‘InstanceHealth’ function which writes a health-check report every interval confirming the function is still running. Rather than duplicating the same process and its configuration on each Function module, we will create a library which contains a single function to do the above process and reference it.

d2.png

For the first step, we need to add the FunctionsInDepedencies tag inside PropertyGroup in the Azure Function project .csproj file. This will instruct the Azure Function SDK to load functions defined in referenced libraries.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    . . .
	<FunctionsInDependencies>true</FunctionsInDependencies>
  </PropertyGroup>
  . . .
</Project>

Now we will make a library to be referenced by the function:

  • Right click Solution → Add new project → Create new Class library
  • Make sure the framework is compatible. For example in my case the Function Project is in .NET 6.0 and shared library with function is .NetStandard2.1

d3.png

Add Package to write function trigger to the .csproj file. Required packages will be automatically installed on build

//Project: Shared.HealthCheckFunction

<ItemGroup>
  ...
  <PackageReference Include="Microsoft.Azure.WebJobs.Extensions" Version="3.0.6" />
</ItemGroup>

Create a class with a function inside the library. In this example we are creating an interval based function using TimerTrigger set to run every one minute.

//Project: Shared.HealthCheckFunction
//Filename: HealthCheckFunction.cs

public class HealthCheckFunction
{ 
    HealthCheckConfig config;

    public HealthCheckFunction(HealthCheckConfig config)
    {
        this.config = config;
    }

    [FunctionName("HealthCheck")]
    public async Task Run([TimerTrigger("0 */1 * * * *")] TimerInfo timer, ILogger log, CancellationToken ct)
    {            
        log.LogInformation($"[HealthCheck] From module {config.ModuleName}");
    }
}
//Project: Shared.HealthCheckFunction
//Filename: HealthCheckConfig.cs

public class HealthCheckConfig
{
    public string ModuleName { get; set; }
}

To assign the HealthCheckConfig object, we are using Dependency Injection by creating a ServiceCollection class.

//Project: Shared.HealthCheckFunction
//Filename: ServiceCollectionExtensions.cs

namespace Microsoft.Extensions.DependencyInjection
{
    public static class HealthCheckServiceCollectionExtensions
    {
        public static IServiceCollection AddHealthCheckBindings(this IServiceCollection services, string moduleName)
        {
            services.AddScoped(_ => new HealthCheckConfig() { ModuleName = moduleName });
            return services;
        }
    }
}

Reference the finished library to the main projects. Then we will add the ServiceExtension configuration to the Startup class.

d4.png

//Project: ModuleFunction1
//Filename: Startup.cs

public class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        // Get Function AppSetting values for cloud deployment or local.settings.json for local
        var configuration = builder.Services.BuildServiceProvider().GetRequiredService<IConfiguration>();

        builder.Services.AddHealthCheckBindings(configuration["Module_Name"]);
        . . .
    }
}

Put the Module_Name key with string values on local.settings.json or Azure Function App’s Configuration based on where you deploy the Function.

{
  "IsEncrypted": false,
  "Values": {
      "Module_Name": "ModuleFunction1"
  }
}

When all configurations are done, now we can run the Function project to test it. HealthCheckFunction will be registered and running like other functions.

d5.png

Conclusion

By distributing the common-use function to the libraries it will help improve the extensibility of the Azure Function projects.

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?