我有一个用 C# 编写的 .NET 6 Azure Function,它没有任何 Program.cs
或 Startup.cs
类。它只具有 .cs
文件中我需要的所有端点(GET
、POST
、PUT
等)。
该函数运行正常,但我与 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/