Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 3.7.0 (2025-07-07)

## Features

* **Dependency Injection**: Added `AddCouchContext` overloads that supply the service provider to the caller ([#210](https://github.com/matteobortolazzo/couchdb-net/pull/210))

# 3.6.1 (2024-04-23)

## Bugs
Expand Down
6 changes: 3 additions & 3 deletions LATEST_CHANGE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# 3.6.1 (2024-04-23)
# 3.7.0 (2025-07-07)

## Bugs
## Features

* **Change feed**: Fixed an issue causing an endless change notification for all documents under certain conditions ([#200](https://github.com/matteobortolazzo/couchdb-net/pull/201))
* **Dependency Injection**: Added `AddCouchContext` overloads that supply the service provider to the caller ([#210](https://github.com/matteobortolazzo/couchdb-net/pull/210))
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
using Autofac;
using CouchDB.Driver.Options;
using System;
using System;
using Autofac;
using CouchDB.Driver.Helpers;
using CouchDB.Driver.Options;

namespace CouchDB.Driver.DependencyInjection.Autofac
{
/// <summary>
/// Provides extension methods to register CouchDB contexts with Autofac.
/// </summary>
public static class AutofacRegistrationExtensions
{
/// <summary>
/// Registers a CouchDB context of type <typeparamref name="TContext" /> with the specified configuration delegate.
/// </summary>
/// <typeparam name="TContext">The type of the CouchDB context to register.</typeparam>
/// <param name="builder">The Autofac container builder.</param>
/// <param name="optionBuilderAction">
/// An action delegate that configures the <see cref="CouchOptionsBuilder{TContext}" />.
/// </param>
/// <returns>The modified <see cref="ContainerBuilder" />.</returns>
/// <exception cref="ArgumentNullException">
/// Thrown if <paramref name="builder" /> or <paramref name="optionBuilderAction" /> is <c>null</c>.
/// </exception>
public static ContainerBuilder AddCouchContext<TContext>(this ContainerBuilder builder,
Action<CouchOptionsBuilder<TContext>> optionBuilderAction)
where TContext : CouchContext
Expand All @@ -27,5 +42,46 @@ public static ContainerBuilder AddCouchContext<TContext>(this ContainerBuilder b

return builder;
}

/// <summary>
/// Registers a CouchDB context of type <typeparamref name="TContext" /> using a factory that can resolve services from
/// the Autofac container.
/// </summary>
/// <typeparam name="TContext">The type of the CouchDB context to register.</typeparam>
/// <param name="builder">The Autofac container builder.</param>
/// <param name="optionBuilderFactory">
/// A factory function that receives an <see cref="IComponentContext" /> and returns a configured
/// <see cref="CouchOptionsBuilder{TContext}" />.
/// </param>
/// <returns>The modified <see cref="ContainerBuilder" />.</returns>
/// <exception cref="ArgumentNullException">
/// Thrown if <paramref name="builder" /> or <paramref name="optionBuilderFactory" /> is <c>null</c>.
/// </exception>
public static ContainerBuilder AddCouchContext<TContext>(
this ContainerBuilder builder,
Func<IComponentContext, CouchOptionsBuilder<TContext>> optionBuilderFactory)
where TContext : CouchContext
{
Check.NotNull(builder, nameof(builder));
Check.NotNull(optionBuilderFactory, nameof(optionBuilderFactory));

builder
.Register(optionBuilderFactory)
.SingleInstance()
.AsSelf()
.As<CouchOptionsBuilder<TContext>>();

builder
.Register(ctx => ctx.Resolve<CouchOptionsBuilder<TContext>>().Options)
.As<CouchOptions<TContext>>()
.SingleInstance();

builder
.RegisterType<TContext>()
.AsSelf()
.SingleInstance();

return builder;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,68 @@

namespace CouchDB.Driver.DependencyInjection
{
/// <summary>
/// Provides extension methods for registering CouchDB contexts with the dependency injection container.
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// Registers a CouchDB context of type <typeparamref name="TContext" /> with the specified configuration delegate.
/// </summary>
/// <typeparam name="TContext">The type of the Couch context to register.</typeparam>
/// <param name="services">The service collection to add the context to.</param>
/// <param name="optionBuilderAction">
/// An action delegate that configures the <see cref="CouchOptionsBuilder{TContext}" /> used to create the context.
/// </param>
/// <returns>The modified <see cref="IServiceCollection" />.</returns>
/// <exception cref="ArgumentNullException">
/// Thrown if <paramref name="services" /> or <paramref name="optionBuilderAction" /> is <c>null</c>.
/// </exception>
public static IServiceCollection AddCouchContext<TContext>(this IServiceCollection services,
Action<CouchOptionsBuilder<TContext>> optionBuilderAction)
where TContext : CouchContext
{
Check.NotNull(services, nameof(services));
Check.NotNull(optionBuilderAction, nameof(optionBuilderAction));

var builder = new CouchOptionsBuilder<TContext>();
optionBuilderAction?.Invoke(builder);
return services
.AddSingleton(builder.Options)
.AddSingleton<TContext>();
}

/// <summary>
/// Registers a CouchDB context of type <typeparamref name="TContext" /> with a factory delegate that can resolve
/// services from the container.
/// </summary>
/// <typeparam name="TContext">The type of the Couch context to register.</typeparam>
/// <param name="services">The service collection to add the context to.</param>
/// <param name="optionBuilderFactory">
/// A factory delegate that takes an <see cref="IServiceProvider" /> and returns a configured
/// <see cref="CouchOptionsBuilder{TContext}" />.
/// </param>
/// <returns>The modified <see cref="IServiceCollection" />.</returns>
/// <exception cref="ArgumentNullException">
/// Thrown if <paramref name="services" /> or <paramref name="optionBuilderFactory" /> is <c>null</c>.
/// </exception>
public static IServiceCollection AddCouchContext<TContext>(
this IServiceCollection services,
Func<IServiceProvider, CouchOptionsBuilder<TContext>> optionBuilderFactory)
where TContext : CouchContext
{
Check.NotNull(services, nameof(services));
Check.NotNull(optionBuilderFactory, nameof(optionBuilderFactory));

services.AddSingleton<CouchOptions<TContext>>(sp =>
{
CouchOptionsBuilder<TContext>? builder = optionBuilderFactory(sp);
return builder.Options;
});

services.AddSingleton<TContext>();

return services;
}
}
}
}
2 changes: 1 addition & 1 deletion src/azure-pipelines.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
variables:
BuildConfiguration: Release
PackageVersion: '3.6.1'
PackageVersion: '3.7.0'

trigger:
branches:
Expand Down