var bucket = await _namedBucketProvider.GetBucketAsync();
var scope = await bucket.ScopeAsync(_scopeName);
var collection = await scope.CollectionAsync(_collectionName);
I use only one collection per instance. Probably a lot of my colleagues have the same use cases. What do you think about adding such interfaces?
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddCouchbaseCollection<T>(this IServiceCollection services, string bucketName, string scopeName = "_default", string collectionName = "_default")
where T : class, INamedCollectionProvider
{ }
public static IServiceCollection AddCouchbaseCollection<T, TBucketProvier>(this IServiceCollection services, string scopeName = "_default", string collectionName = "_default")
where T : class, INamedCollectionProvider
where TBucketProvier: class, INamedBucketProvider
{ }
public static IServiceCollection AddCouchbaseScope<T>(this IServiceCollection services, string bucketName, string scopeName = "_default")
where T : class, INamedScopeProvider
{ }
public static IServiceCollection AddCouchbaseScope<T, TBucketProvier>(this IServiceCollection services, string scopeName = "_default")
where T : class, INamedScopeProvider
where TBucketProvier : class, INamedBucketProvider
{ }
}
public interface INamedScopeProvider
{
public string BucketName { get; }
public string ScopeName { get; }
public ValueTask<IScope> GetScopeAsync();
}
public interface INamedCollectionProvider
{
public string BucketName { get; }
public string ScopeName { get; }
public string CollectionName { get; }
public ValueTask<ICouchbaseCollection> GetCollectionAsync();
}
Looks interesting, have you considered doing an implementation and pushing a pull request? The SDK is open source and contributions like this can be very useful to others.
Feel free to reach out if you need any assistance.
public interface IMyBucket : INamedBucketProvider
{
}
public interface IMyDefaultCollectionProvider : INamedCollectionProvider
{
}
public interface IMyCollectionProvider : INamedCollectionProvider
{
}
services.AddCouchbaseBucket<IMyBucket>("my-bucket", builder => {
builder.AddDefaultCollection<IMyDefaultCollectionProvider>();
builder.AddCollection<IMyCollection>("my-scope", "my-collection");
});
One decision I made, which may or may not be correct, was to avoid the intermediate INamedScopeProvider. So far I haven’t come up with a good reason why you would inject a scope, since it’s really just an intermediate layer to get to collections anyway. But I’m open to arguments on this point.
Another alternative syntax which may be worth considering, which reduces repetition of the scope name during building:
After some further thought, I went ahead and changed to my second idea, AddScope chained with AddCollection calls. I think that will be much cleaner since many scopes will have multiple collections.
That’s a good point. But I’d argue those properties are probably better placed directly on IScope and ICouchbaseCollection. That way they’d be available more broadly. Thoughts?