Normalmente in un progetto .NET Core avrei creato una classe 'boostrap' per configurare il mio servizio insieme ai comandi di registrazione DI. Questo è di solito un metodo di estensione in IServiceCollectioncui posso chiamare un metodo simile .AddCosmosDbServicee tutto il necessario è "autonomo" nella classe statica contenente quel metodo. La chiave però è che il metodo ottiene un IConfigurationdalStartup classe.
Ho lavorato con DI in Funzioni di Azure in passato ma non ho ancora incontrato questo requisito specifico.
Sto usando il IConfigurationper legare a una classe concreta con proprietà che corrispondono alle impostazioni di entrambi i mieilocal.settings.json che delle impostazioni di sviluppo / produzione dell'applicazione quando la funzione viene distribuita in Azure.
CosmosDbClientSettings.cs
/// <summary>
/// Holds configuration settings from local.settings.json or application configuration
/// </summary>
public class CosmosDbClientSettings
{
public string CosmosDbDatabaseName { get; set; }
public string CosmosDbCollectionName { get; set; }
public string CosmosDbAccount { get; set; }
public string CosmosDbKey { get; set; }
}
BootstrapCosmosDbClient.cs
public static class BootstrapCosmosDbClient
{
/// <summary>
/// Adds a singleton reference for the CosmosDbService with settings obtained by injecting IConfiguration
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
/// <returns></returns>
public static async Task<CosmosDbService> AddCosmosDbServiceAsync(
this IServiceCollection services,
IConfiguration configuration)
{
CosmosDbClientSettings cosmosDbClientSettings = new CosmosDbClientSettings();
configuration.Bind(nameof(CosmosDbClientSettings), cosmosDbClientSettings);
CosmosClientBuilder clientBuilder = new CosmosClientBuilder(cosmosDbClientSettings.CosmosDbAccount, cosmosDbClientSettings.CosmosDbKey);
CosmosClient client = clientBuilder.WithConnectionModeDirect().Build();
CosmosDbService cosmosDbService = new CosmosDbService(client, cosmosDbClientSettings.CosmosDbDatabaseName, cosmosDbClientSettings.CosmosDbCollectionName);
DatabaseResponse database = await client.CreateDatabaseIfNotExistsAsync(cosmosDbClientSettings.CosmosDbDatabaseName);
await database.Database.CreateContainerIfNotExistsAsync(cosmosDbClientSettings.CosmosDbCollectionName, "/id");
services.AddSingleton<ICosmosDbService>(cosmosDbService);
return cosmosDbService;
}
}
Startup.cs
public class Startup : FunctionsStartup
{
public override async void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddHttpClient();
await builder.Services.AddCosmosDbServiceAsync(**need IConfiguration reference**); <--where do I get IConfiguration?
}
}
Ovviamente aggiungere un campo privato per IConfigurationin Startup.csnon funzionerà in quanto deve essere popolato con qualcosa e ho anche letto che usare DI per IConfigurationnon è una buona idea .
Ho anche provato a utilizzare il modello di opzioni come descritto qui e implementato come tale:
builder.Services.AddOptions<CosmosDbClientSettings>()
.Configure<IConfiguration>((settings, configuration) => configuration.Bind(settings));
Mentre questo funzionerebbe per iniettare una IOptions<CosmosDbClientSettings>classe non statica, sto usando una classe statica per conservare il mio lavoro di configurazione.
Qualche suggerimento su come posso farlo funzionare o una possibile soluzione? Preferirei mantenere tutta la configurazione in un unico posto (file bootstrap).
host.jsonparametri non vengono utilizzati, in particolare,routePrefix