Azure / Azure/Microsoft.Extensions.Caching.Cosmos

Very limited DI registration options, creates a paradox between eager, and post-build services.

Open
#78 7 comments 1 reaction 1 assignee Claimed by @ealsur View on GitHub
Dominant language
C#
Stars
55
Forks
18
PR merge metrics
No merged PRs in 30d

Description

There seems to be no way to use the Options pattern, and default azure credentials.

I have a section in `appSettings.json` as such:

```json
"CosmosCache": {
"AccountEndpoint": "https://azure.url:443",
"ContainerName": "containerName",
"DatabaseName": "databaseName"
}
```

I'm registering these within the DI, using `CosmosCacheConfiguration` as a POCO:

```csharp
services.Configure(configuration.GetRequiredSection("CosmosCache"));
```

We also use default azure tokens:

```csharp
services.AddSingleton();
```

However, all of this requires me to late-bind the cosmos cache, but your package can only be eagerly bound, meaning I cannot get to any of the values required to add cosmos, with what's available out of the box:

```cs
services.AddCosmosCache(o =>
{
o.ClientBuilder = new CosmosClientBuilder(CannotGetTo.AccountEndpoint, CannotGetTo.TokenCredential);
o.ContainerName = CannotGetTo.ContainerName;
o.DatabaseName = CannotGetTo.DatabaseName;
});
```

If I try to create my own registrar, then have no way of creating an `IOptions`, or `IOptionsMonitor`, which are the only two available constructors for `CosmosCache`.

```csharp
public static IServiceCollection AddCosmosCache(this IServiceCollection services, IConfiguration configuration)
{
services.Configure(configuration.GetRequiredSection("CosmosCache"));
services.AddSingleton(sp =>
{
var config = sp.GetRequiredService>().Value;
var tokenCredential = sp.GetRequiredService();

// ERROR: System.InvalidOperationException: 'The service collection cannot be modified because it is read-only.'
services.Configure(CosmosCacheOptionsFactory);

// ERROR: CosmosCacheOptions is not configured.
var service = sp.GetRequiredService>();

return new CosmosCache(service);

void CosmosCacheOptionsFactory(CosmosCacheOptions o)
{
o.ClientBuilder = new CosmosClientBuilder(config.AccountEndpoint, tokenCredential);
o.ContainerName = config.ContainerName;
o.DatabaseName = config.DatabaseName;
}
});
}
```

So we have a paradox in which we can't eager-load the service because we have no access to any of the properties that the service needs; and we can't load the service via an implementation factory, because we can't add to the service collection a posterori.

Has this been resolved any other way? Or, is it possible to get a more robust registration procedure? There may be a more obscure way of resolving this with the package as it stands, but I can't see the path to making it work, with what I currently understand about M.E.DI.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.