.netazureazure-functionsstackexchange.redis

Azure Redis Cache not found in AzureClientFactoryBuilder Isolated .NET 8


I'm working on an Isolated .NET 8 Azure Functions project

I want to use Azure Redis Cache using the IServiceCollection and AzureClientFactoryBuilder in the program.cs file.

I'm able to use ServiceBusClient and EventHubProducerClient by installing the following packages:

Microsoft.Azure.Functions.Worker.Extensions.EventHubs Microsoft.Azure.Functions.Worker.Extensions.ServiceBus

services.AddAzureClients(clientBuilder=>{ clientBuilder.AddEventHubProducerClient(eventHubConnectionString,eventHubName); clientBuilder.AddServiceBusClient(serviceBusConnectionString); }

But I cannot do the same for Azure Redis Cache after installing the following package:

Microsoft.Azure.Functions.Worker.Extensions.Redis

I would expect to find a method like:

services.AddAzureClients(clientBuilder=>{ clientBuilder.AddRedisCache(redisCacheConnectionString); }

But I can't find any method related to Redis Cache.

Is there something I'm missing?


Solution

  • RedisFunction.cs-

    using System;
    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Extensions.Caching.Distributed;
    using Microsoft.Extensions.Logging;
    
    namespace _78546446
    {
        public class RedisFunction
        {
            private readonly IDistributedCache _cache;
            private readonly ILogger _logger;
    
            public RedisFunction(IDistributedCache cache, ILoggerFactory loggerFactory)
            {
                _cache = cache;
                _logger = loggerFactory.CreateLogger<RedisFunction>();
            }
    
            [Function("RedisFunction")]
            public async Task Run([TimerTrigger("0 * * * * *")] TimerInfo myTimer)
            {
                _logger.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
                
                if (myTimer.ScheduleStatus is not null)
                {
                    _logger.LogInformation($"Next timer schedule at: {myTimer.ScheduleStatus.Next}");
                }
    
                // Example of setting a value in Redis
                await _cache.SetStringAsync("TestKey", "TestValue");
    
                var value = await _cache.GetStringAsync("TestKey");
                _logger.LogInformation($"Retrieved value from Redis: {value}");
            }
        }
    }
    

    .csproj-

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <AzureFunctionsVersion>v4</AzureFunctionsVersion>
        <OutputType>Exe</OutputType>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <RootNamespace>_78546446</RootNamespace>
      </PropertyGroup>
      <ItemGroup>
        <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.22.0" />
        <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.2.0" />
        <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Timer" Version="4.3.0" />
        <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.17.3-preview2" />
        <PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
        <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.2.0" />
        <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.0-preview.4.24267.6" />
      </ItemGroup>
      <ItemGroup>
        <None Update="host.json">
          <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </None>
        <None Update="local.settings.json">
          <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
          <CopyToPublishDirectory>Never</CopyToPublishDirectory>
        </None>
      </ItemGroup>
      <ItemGroup>
        <Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
      </ItemGroup>
    </Project>
    

    Program.cs -

    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    
    var host = new HostBuilder()
        .ConfigureFunctionsWorkerDefaults()
        .ConfigureServices(services =>
        {
            services.AddApplicationInsightsTelemetryWorkerService();
            services.ConfigureFunctionsApplicationInsights();
            services.AddStackExchangeRedisCache(options =>
            {
                options.Configuration = "<redisCacheConnectionString>";
                options.InstanceName = "<AzureRedisCache_instanceName>";
            });
        })
        .Build();
    
    host.Run();
    

    I am able to retrieve a value from Redis.

    Azure Functions Core Tools
    Core Tools Version:       4.0.5801 Commit hash: N/A +5ac2f09758b98257e728dd1b5576ce5ea9ef68ff (64-bit)
    Function Runtime Version: 4.34.1.22669
    
    [2024-05-29T08:42:16.410Z] Found C:\Users\******\78546446\78546446.csproj. Using for user secrets file configuration.
    [2024-05-29T08:42:19.707Z] Azure Functions .NET Worker (PID: 26968) initialized in debug mode. Waiting for debugger to attach...
    [2024-05-29T08:42:19.756Z] Worker process started and initialized.
    
    Functions:
    
            RedisFunction: timerTrigger
    
    For detailed output, run func with --verbose flag.
    [2024-05-29T08:42:20.056Z] Executing 'Functions.RedisFunction' (Reason='Timer fired at 2024-05-29T14:12:20.0254156+05:30', Id=d803ec2c-0db7-4588-b2ae-d09305d69146)
    [2024-05-29T08:42:20.060Z] Trigger Details: UnscheduledInvocationReason: IsPastDue, OriginalSchedule: 2024-05-29T13:28:00.0000000+05:30
    [2024-05-29T08:42:20.159Z] C# Timer trigger function executed at: 5/29/2024 2:12:20 PM
    [2024-05-29T08:42:20.159Z] Next timer schedule at: 5/29/2024 1:28:00 PM
    [2024-05-29T08:42:22.332Z] Retrieved value from Redis: TestValue
    [2024-05-29T08:42:22.366Z] Executed 'Functions.RedisFunction' (Succeeded, Id=d803ec2c-0db7-4588-b2ae-d09305d69146, Duration=2331ms)
    

    You can also configure the cache clients using StackExchange.Redis package.