.NET 5 support for Azure Functions is announced as GA in this blog article!
We can find developer guide at Guide for running functions on .NET 5.0 in Azure and Develop and publish .NET 5 functions using Azure Functions
Today, I want to share how to use DI (Dependency Injection) in this "isolated process" when we use .NET 5.
Reference: Start-up and configuration
Create project
First thing first! We need to create function project by using new template.
1. Install the latest version of Azure Function Core Tools v3. See here for more detail.
2. Once you install the tool, make sure to check the version. It should be higher than 3.0.3381.
func --version
3. Create new folder and initialize the function.
mkdir dotnet5func
cd dotnet5func
func init
4. Now, we can see new option available. Select "dotnet (isolated process".
5. Then, create new function project. Select any trigger as you want. I selected HttpTrigger this time.
func new
6. Enter function name to complete, then run the function and confirm it works as expected.
func start
7. Stop the function and open the project by using Visual Studio Code or Visual Studio.
code .
Configure Dependency Injection
The most important thing to know when use DI is, that we don't need Startup.cs!! We can directly change code in Program.cs to configure DI now.
1.\ Program.cs should looks like below when we scaffold the project.
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Azure.Functions.Worker.Configuration;
namespace dotnet5func
{
public class Program
{
public static void Main()
{
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.Build();
host.Run();
}
}
}
2.\ To use DI, we simply modify HostBuilder. Let's add HttpClient factory. We can simply use ConfigureServices method and use AddHttpClient() which is exactly same as ASP.NET project.
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
namespace dotnet5func
{
public class Program
{
public static void Main()
{
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(s => {
s.AddHttpClient();
})
.Build();
host.Run();
}
}
}
3. Open function code and accept IHttpClientFactory via DI. We need to change several places.
- Remove static keywords so that we can instantiate class
- Add private IHttpClientFactory and receive it via constructor
- Change signature of Run method to make it asynchronous call
I use swapi.dev this time. swapi is a cool api if you love Star Wars. Check out swapi.dev for more detail.
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
namespace dotnet5func
{
public class dotnet5func
{
private readonly IHttpClientFactory clientFactory;
public dotnet5func(IHttpClientFactory clientFactory)
{
this.clientFactory = clientFactory;
}
[Function("dotnet5func")]
public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
FunctionContext executionContext)
{
var logger = executionContext.GetLogger("dotnet5func");
logger.LogInformation("C# HTTP trigger function processed a request.");
var client = clientFactory.CreateClient();
var swapires = await client.GetStringAsync("https://swapi.dev/api/people/1/");
var response = req.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
response.WriteString(swapires);
return response;
}
}
}
4. Run the function again and call the endpoint.
func start
Summary
Even though there are still slight differences between Azure Functions and Web API when we writing code, I can easily and effectively reusing my knowledge once I fill the gap!
I cannot wait .NET 6 release which is LTS next year!
Top comments (2)
How would I make this work with an
IActionResult
as the response type?When and why do you want to use IActionResult?