Skip to content

Commit

Permalink
✨ implement Keyed service injection
Browse files Browse the repository at this point in the history
  • Loading branch information
Odonno committed Nov 14, 2024
1 parent b4e6f8b commit 568d014
Showing 1 changed file with 218 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,157 @@ public static SurrealDbBuilder AddSurreal<T>(
return new SurrealDbBuilder(services);
}

/// <summary>
/// Registers keyed SurrealDB services from a ConnectionString.
/// </summary>
/// <param name="services">Service collection.</param>
/// <param name="serviceKey">The <see cref="ServiceDescriptor.ServiceKey"/> of the service.</param>
/// <param name="connectionString">Connection string to a SurrealDB instance.</param>
/// <param name="lifetime">Service lifetime to register services under. Default value is <see cref="ServiceLifetime.Singleton"/>.</param>
/// <param name="configureCborOptions">An optional action to configure <see cref="CborOptions"/>.</param>
/// <returns>Service collection</returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ArgumentOutOfRangeException"></exception>
/// <exception cref="ArgumentNullException"></exception>
public static SurrealDbBuilder AddKeyedSurreal(
this IServiceCollection services,
object? serviceKey,
string connectionString,
ServiceLifetime lifetime = ServiceLifetime.Singleton,
Action<CborOptions>? configureCborOptions = null
)
{
var configuration = SurrealDbOptions
.Create()
.FromConnectionString(connectionString)
.Build();

return AddKeyedSurreal<ISurrealDbClient>(
services,
serviceKey,
configuration,
lifetime,
configureCborOptions
);
}

/// <summary>
/// Registers SurrealDB services with the specified configuration.
/// </summary>
/// <param name="services">Service collection.</param>
/// <param name="serviceKey">The <see cref="ServiceDescriptor.ServiceKey"/> of the service.</param>
/// <param name="configureOptions">A delegate that is used to configure a <see cref="SurrealDbOptionsBuilder"/>.</param>
/// <param name="lifetime">Service lifetime to register services under. Default value is <see cref="ServiceLifetime.Singleton"/>.</param>
/// <returns>Service collection</returns>
/// <exception cref="ArgumentOutOfRangeException"></exception>
/// <exception cref="ArgumentNullException"></exception>
public static SurrealDbBuilder AddKeyedSurreal(
this IServiceCollection services,
object? serviceKey,
Action<SurrealDbOptionsBuilder> configureOptions,
ServiceLifetime lifetime = ServiceLifetime.Singleton
)
{
var options = SurrealDbOptions.Create();
configureOptions(options);
return AddKeyedSurreal<ISurrealDbClient>(services, serviceKey, options.Build(), lifetime);
}

/// <summary>
/// Registers SurrealDB services with the specified configuration.
/// </summary>
/// <param name="services">Service collection.</param>
/// <param name="serviceKey">The <see cref="ServiceDescriptor.ServiceKey"/> of the service.</param>
/// <param name="configuration">Configuration options.</param>
/// <param name="lifetime">Service lifetime to register services under. Default value is <see cref="ServiceLifetime.Singleton"/>.</param>
/// <param name="configureCborOptions">An optional action to configure <see cref="CborOptions"/>.</param>
/// <returns>Service collection</returns>
/// <exception cref="ArgumentOutOfRangeException"></exception>
/// <exception cref="ArgumentNullException"></exception>
public static SurrealDbBuilder AddKeyedSurreal(
this IServiceCollection services,
object? serviceKey,
SurrealDbOptions configuration,
ServiceLifetime lifetime = ServiceLifetime.Singleton,
Action<CborOptions>? configureCborOptions = null
)
{
return AddKeyedSurreal<ISurrealDbClient>(
services,
serviceKey,
configuration,
lifetime,
configureCborOptions
);
}

/// <summary>
/// Registers SurrealDB services with the specified configuration.
/// </summary>
/// <typeparam name="T">Type of <see cref="ISurrealDbClient"/> to register.</typeparam>
/// <param name="services">Service collection.</param>
/// <param name="serviceKey">The <see cref="ServiceDescriptor.ServiceKey"/> of the service.</param>
/// <param name="configuration">Configuration options.</param>
/// <param name="lifetime">Service lifetime to register services under. Default value is <see cref="ServiceLifetime.Singleton"/>.</param>
/// <param name="configureCborOptions">An optional action to configure <see cref="CborOptions"/>.</param>
/// <returns>Service collection</returns>
/// <exception cref="ArgumentOutOfRangeException"></exception>
/// <exception cref="ArgumentNullException"></exception>
public static SurrealDbBuilder AddKeyedSurreal<T>(
this IServiceCollection services,
object? serviceKey,
SurrealDbOptions configuration,
ServiceLifetime lifetime = ServiceLifetime.Singleton,
Action<CborOptions>? configureCborOptions = null
)
where T : ISurrealDbClient
{
if (configuration.Endpoint is null)
throw new ArgumentNullException(nameof(configuration), "The endpoint is required.");

bool shouldRegisterHttpClient = new Uri(configuration.Endpoint).Scheme is "http" or "https";
if (shouldRegisterHttpClient)
{
RegisterHttpClient(services, configuration.Endpoint);
}

var classClientType = typeof(SurrealDbClient);
var interfaceClientType = typeof(ISurrealDbClient);
var type = typeof(T);

bool isBaseType = type == classClientType || type == interfaceClientType;

if (isBaseType)
{
RegisterKeyedSurrealDbClient<ISurrealDbClient>(
services,
serviceKey,
configuration,
lifetime,
configureCborOptions
);
RegisterKeyedSurrealDbClient<SurrealDbClient>(
services,
serviceKey,
configuration,
lifetime,
configureCborOptions
);
}
else
{
RegisterKeyedSurrealDbClient<T>(
services,
serviceKey,
configuration,
lifetime,
configureCborOptions
);
}

return new SurrealDbBuilder(services);
}

private static void RegisterHttpClient(IServiceCollection services, string endpoint)
{
var uri = new Uri(endpoint);
Expand Down Expand Up @@ -240,4 +391,71 @@ private static void RegisterSurrealDbClient<T>(
);
}
}

private static void RegisterKeyedSurrealDbClient<T>(
IServiceCollection services,
object? serviceKey,
SurrealDbOptions configuration,
ServiceLifetime lifetime,
Action<CborOptions>? configureCborOptions = null
)
{
switch (lifetime)
{
case ServiceLifetime.Singleton:
services.AddKeyedSingleton(
typeof(T),
serviceKey,
(serviceProvider, _) =>
{
return new SurrealDbClient(
configuration,
serviceProvider,
serviceProvider.GetRequiredService<IHttpClientFactory>(),
configureCborOptions,
serviceProvider.GetService<ILoggerFactory>()
);
}
);
break;
case ServiceLifetime.Scoped:
services.AddKeyedScoped(
typeof(T),
serviceKey,
(serviceProvider, _) =>
{
return new SurrealDbClient(
configuration,
serviceProvider,
serviceProvider.GetRequiredService<IHttpClientFactory>(),
configureCborOptions,
serviceProvider.GetService<ILoggerFactory>()
);
}
);
break;
case ServiceLifetime.Transient:
services.AddKeyedTransient(
typeof(T),
serviceKey,
(serviceProvider, _) =>
{
return new SurrealDbClient(
configuration,
serviceProvider,
serviceProvider.GetRequiredService<IHttpClientFactory>(),
configureCborOptions,
serviceProvider.GetService<ILoggerFactory>()
);
}
);
break;
default:
throw new ArgumentOutOfRangeException(
nameof(lifetime),
lifetime,
"Invalid service lifetime."
);
}
}
}

0 comments on commit 568d014

Please sign in to comment.