Skip to content

feat: implement clickhouse connection factory with IClickhouseDataSource #305

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 7, 2025
Merged
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
Original file line number Diff line number Diff line change
@@ -1,28 +1,17 @@
using System.Data;
using ClickHouse.Client.ADO;
using ClickHouse.Client;
using Cnblogs.Architecture.Ddd.Infrastructure.Dapper;

namespace Cnblogs.Architecture.Ddd.Cqrs.Dapper.Clickhouse;

/// <summary>
/// Clickhouse connection factory.
/// </summary>
public class ClickhouseDbConnectionFactory : IDbConnectionFactory
public class ClickhouseDbConnectionFactory(IClickHouseDataSource dataSource) : IDbConnectionFactory
{
private readonly string _connectionString;

/// <summary>
/// Create a clickhouse connection factory.
/// </summary>
/// <param name="connectionString">The connection string.</param>
public ClickhouseDbConnectionFactory(string connectionString)
{
_connectionString = connectionString;
}

/// <inheritdoc />
public IDbConnection CreateDbConnection()
{
return new ClickHouseConnection(_connectionString);
return dataSource.CreateConnection();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public static void UseClickhouse<TContext>(
string connectionString)
where TContext : ClickhouseDapperContext
{
builder.UseDbConnectionFactory(new ClickhouseDbConnectionFactory(connectionString));
builder.UseDbConnectionFactory<ClickhouseDbConnectionFactory>();
builder.Services.AddClickHouseDataSource(connectionString);
builder.Services.AddSingleton(new ClickhouseContextOptions<TContext>(connectionString));
builder.Services.Configure<ClickhouseContextCollection>(x => x.Add<TContext>());
builder.Services.AddHostedService<ClickhouseInitializeHostedService>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,23 @@ public DapperConfigurationBuilder(IServiceCollection services)
/// <param name="factory">工厂对象。</param>
/// <typeparam name="TFactory">工厂类型。</typeparam>
public void UseDbConnectionFactory<TFactory>(TFactory factory)
where TFactory : IDbConnectionFactory
where TFactory : class, IDbConnectionFactory
{
Services.AddSingleton(factory);
Services.Configure<DbConnectionFactoryCollection>(
c => c.AddDbConnectionFactory(_dapperContextTypeName, factory));
c => c.AddDbConnectionFactory(_dapperContextTypeName, typeof(TFactory)));
}

/// <summary>
/// Add <typeparamref name="TFactory"/> as <see cref="IDbConnectionFactory"/> and get instance from DI when used.
/// </summary>
/// <typeparam name="TFactory">The factory type.</typeparam>
public void UseDbConnectionFactory<TFactory>()
where TFactory : class, IDbConnectionFactory
{
Services.AddSingleton<TFactory>();
Services.Configure<DbConnectionFactoryCollection>(
c => c.AddDbConnectionFactory(_dapperContextTypeName, typeof(TFactory)));
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ public abstract class ClickhouseDapperContext : DapperContext
/// </summary>
/// <param name="dbConnectionFactoryCollection">The underlying <see cref="IDbConnectionFactory"/> collection.</param>
/// <param name="options">The options used for this context.</param>
/// <param name="serviceProvider">The service provider to use.</param>
protected ClickhouseDapperContext(
IOptions<DbConnectionFactoryCollection> dbConnectionFactoryCollection,
ClickhouseContextOptions options)
: base(dbConnectionFactoryCollection)
ClickhouseContextOptions options,
IServiceProvider serviceProvider)
: base(dbConnectionFactoryCollection, serviceProvider)
{
_options = options;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="ClickHouse.Client" Version="7.9.1" />
<PackageReference Include="ClickHouse.Client" Version="7.10.1" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System.Data;

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

namespace Cnblogs.Architecture.Ddd.Infrastructure.Dapper;
Expand All @@ -13,9 +13,13 @@ public abstract class DapperContext
/// 创建一个 DapperContext。
/// </summary>
/// <param name="dbConnectionFactoryCollection">数据库连接工厂集合。</param>
protected DapperContext(IOptions<DbConnectionFactoryCollection> dbConnectionFactoryCollection)
/// <param name="sp">The service provider to get connection factory</param>
protected DapperContext(IOptions<DbConnectionFactoryCollection> dbConnectionFactoryCollection, IServiceProvider sp)
{
DbConnectionFactory = dbConnectionFactoryCollection.Value.GetFactory(GetType().Name);
var type = dbConnectionFactoryCollection.Value.GetFactory(GetType().Name);
DbConnectionFactory = sp.GetRequiredService(type) as IDbConnectionFactory
?? throw new InvalidOperationException(
$"No DbConnectionFactory(type: {type.Name}) configured.");
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@
/// </summary>
public class DbConnectionFactoryCollection
{
private readonly Dictionary<string, IDbConnectionFactory> _factories = new();
private readonly Dictionary<string, Type> _factories = new();

/// <summary>
/// 添加数据库连接工厂。
/// </summary>
/// <param name="name">名称。</param>
/// <param name="factory">工厂示例。</param>
/// <exception cref="InvalidOperationException">Throw when <paramref name="name"/> already been registered with other factory.</exception>
public void AddDbConnectionFactory(string name, IDbConnectionFactory factory)
public void AddDbConnectionFactory(string name, Type factory)
{
if (_factories.TryGetValue(name, out var value))
{
throw new InvalidOperationException(
$"The dapper context already configured with db connection factory: {value.GetType().Name}");
$"The dapper context already configured with db connection factory: {value.Name}");
}

_factories.Add(name, factory);
Expand All @@ -29,7 +29,7 @@ public void AddDbConnectionFactory(string name, IDbConnectionFactory factory)
/// </summary>
/// <param name="name">名称。</param>
/// <returns>工厂示例。</returns>
public IDbConnectionFactory GetFactory(string name)
public Type GetFactory(string name)
{
return _factories[name];
}
Expand Down