c# - 如何在 Azure Function 启动时仅连接到 Cosmos DB 一次?

标签 c# .net azure azure-cosmosdb

我有一个用 C# 编写的 .NET 6 Azure Function,它没有任何 Program.csStartup.cs 类。它只具有 .cs 文件中我需要的所有端点(GETPOSTPUT 等)。

该函数运行正常,但我与 Cosmos DB 的连接出现问题。我只想在函数启动时连接一次,然后在所有其他端点中使用相同的连接。

我怎样才能做到这一点?现在看来我每次都创建一个新的数据库对象,这似乎根本不是最佳的。

最佳答案

Azure SDK指出您应该为 Cosmos DB 客户端使用单例。

下面是来自 Microsoft 的使用静态方法的示例:https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/performance-tips-dotnet-sdk-v3?tabs=trace-net-core#sdk-usage 。但是,我会选择函数 dependency injection .

我的.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.Cosmos" Version="3.32.2" />
    <PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.0.1" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>

Startup.cs

[assembly: FunctionsStartup(typeof(Startup))]

namespace MyFunctionApp;

public class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        IConfiguration configuration = builder.GetContext().Configuration;
        builder.Services.AddSingleton<CosmosClient>((serviceProvider) =>
        {
            return new CosmosClient(configuration["CONNECTION_STRING"]);
        });
    }
}

ProductApi.cs

public class ProductApi 
{
   private readonly CosmosClient _client;
   public ProductApi(CosmosClient client) 
   {
        _client = client;
   }

    [FunctionName("GetProducts")]
    public async Task<IActionResult> Get(
        [HttpTrigger(AuthorizationLevel.Anonymous, methods: "get", Route = "products")] HttpRequest req,
        ILogger log)
    {
        // Get stuff from database/containers.
    }
}

这只是一个简单的例子。我不会直接使用 CosmosClient ,而是将其放在某种服务后面(不要忘记为 DI 注册它)。

public interface IProductService
{
    Task<IEnumerable<Product>> Read();
}

class ProductService : IProductService
{
    private readonly CosmosClient client;
    private readonly Database database;
    private readonly Container container;

    public ProductService(CosmosClient cosmosClient)
    {
        client = cosmosClient;
        database = client.GetDatabase("tailwind");
        container = client.GetContainer(database.Id, "products");
    }

    public async Task<IEnumerable<Product>> Read()
    {
        var feedIterator = container.GetItemLinqQueryable<Product>().ToFeedIterator();
        var batches = new List<Product>();

        while (feedIterator.HasMoreResults)
            batches.AddRange(await feedIterator.ReadNextAsync().ConfigureAwait(false));

        return batches;
    }
}

关于c# - 如何在 Azure Function 启动时仅连接到 Cosmos DB 一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75751102/

相关文章:

c# - ASP.Net Listview 空 ItemTemplate 不显示

azure - 如何在 Azure Functions (v2) 上启用 GZIP 压缩?

azure - 获取有权访问 Azure 资源的用户和组

azure - 获取/刷新 TFS OAuth token 因 invalid_grant 失败

c# - DataTable 不显示分钟和秒

javascript - 如何使用 JavaScript 在 asp.net 中基于另一个文本框的文本框上进行验证?

c# - C# winform中的excel列选择查询

两个协变接口(interface)的 C# 协变问题

c# - 使用哪个 linq 在当前集合中的集合中进行集合搜索

c# - 我应该对这个类进行单元测试吗?