Skip to content

Commit a755ca0

Browse files
authored
fix: isolate clickhouse db connection factory between different clickhouse db contexts (#327)
1 parent 98ea614 commit a755ca0

File tree

16 files changed

+249
-9
lines changed

16 files changed

+249
-9
lines changed

src/Cnblogs.Architecture.Ddd.Cqrs.Dapper.Clickhouse/ClickhouseDbConnectionFactory.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
using System.Data;
22
using ClickHouse.Client;
33
using Cnblogs.Architecture.Ddd.Infrastructure.Dapper;
4+
using Cnblogs.Architecture.Ddd.Infrastructure.Dapper.Clickhouse;
45

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

78
/// <summary>
89
/// Clickhouse connection factory.
910
/// </summary>
10-
public class ClickhouseDbConnectionFactory(IClickHouseDataSource dataSource) : IDbConnectionFactory
11+
/// <typeparam name="TContext">The <see cref="ClickhouseDapperContext"/> this connection factory belongs to.</typeparam>
12+
public class ClickhouseDbConnectionFactory<TContext>(IClickHouseDataSource dataSource) : IDbConnectionFactory
13+
where TContext : ClickhouseDapperContext
1114
{
1215
/// <inheritdoc />
1316
public IDbConnection CreateDbConnection()

src/Cnblogs.Architecture.Ddd.Cqrs.Dapper.Clickhouse/DapperConfigurationBuilderExtension.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using ClickHouse.Client;
12
using Cnblogs.Architecture.Ddd.Cqrs.Dapper.Clickhouse;
23
using Cnblogs.Architecture.Ddd.Infrastructure.Dapper.Clickhouse;
34
using Microsoft.Extensions.DependencyInjection;
@@ -21,8 +22,11 @@ public static void UseClickhouse<TContext>(
2122
string connectionString)
2223
where TContext : ClickhouseDapperContext
2324
{
24-
builder.UseDbConnectionFactory<ClickhouseDbConnectionFactory>();
25-
builder.Services.AddClickHouseDataSource(connectionString);
25+
var contextName = typeof(TContext).Name;
26+
builder.UseDbConnectionFactory(sp
27+
=> new ClickhouseDbConnectionFactory<TContext>(
28+
sp.GetRequiredKeyedService<IClickHouseDataSource>(contextName)));
29+
builder.Services.AddClickHouseDataSource(connectionString, serviceKey: contextName);
2630
builder.Services.AddSingleton(new ClickhouseContextOptions<TContext>(connectionString));
2731
builder.Services.Configure<ClickhouseContextCollection>(x => x.Add<TContext>());
2832
builder.Services.AddHostedService<ClickhouseInitializeHostedService>();

src/Cnblogs.Architecture.Ddd.Cqrs.Dapper.SqlServer/Cnblogs.Architecture.Ddd.Cqrs.Dapper.SqlServer.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
</ItemGroup>
1212

1313
<ItemGroup>
14-
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.2" />
14+
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.1.1" />
1515
</ItemGroup>
1616

1717
</Project>

src/Cnblogs.Architecture.Ddd.Cqrs.Dapper/DapperConfigurationBuilder.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,19 @@ public void UseDbConnectionFactory<TFactory>(TFactory factory)
3636
c => c.AddDbConnectionFactory(_dapperContextTypeName, typeof(TFactory)));
3737
}
3838

39+
/// <summary>
40+
/// Add <typeparamref name="TFactory"/> by <paramref name="implementationFactory"/>.
41+
/// </summary>
42+
/// <param name="implementationFactory">The object initializer.</param>
43+
/// <typeparam name="TFactory">The type of the factory.</typeparam>
44+
public void UseDbConnectionFactory<TFactory>(Func<IServiceProvider, TFactory> implementationFactory)
45+
where TFactory : class
46+
{
47+
Services.AddSingleton(implementationFactory);
48+
Services.Configure<DbConnectionFactoryCollection>(
49+
c => c.AddDbConnectionFactory(_dapperContextTypeName, typeof(TFactory)));
50+
}
51+
3952
/// <summary>
4053
/// Add <typeparamref name="TFactory"/> as <see cref="IDbConnectionFactory"/> and get instance from DI when used.
4154
/// </summary>

src/Cnblogs.Architecture.Ddd.Cqrs.Dapper/ServiceCollectionInjector.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ public static class ServiceCollectionInjector
1818
public static DapperConfigurationBuilder<TContext> AddDapperContext<TContext>(this IServiceCollection services)
1919
where TContext : DapperContext
2020
{
21+
var alreadyAdded = services.Any(s => s.ServiceType == typeof(TContext));
22+
if (alreadyAdded)
23+
{
24+
throw new InvalidOperationException($"Dapper context with name {typeof(TContext).Name} already added");
25+
}
26+
2127
services.AddScoped<TContext>();
2228
return new DapperConfigurationBuilder<TContext>(services);
2329
}

src/Cnblogs.Architecture.Ddd.Infrastructure.CacheProviders.Redis/Cnblogs.Architecture.Ddd.Infrastructure.CacheProviders.Redis.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
</ItemGroup>
1313

1414
<ItemGroup>
15-
<PackageReference Include="StackExchange.Redis" Version="2.8.58" />
15+
<PackageReference Include="StackExchange.Redis" Version="2.9.11" />
1616
</ItemGroup>
1717

1818
</Project>

src/Cnblogs.Architecture.Ddd.Infrastructure.MongoDb/Cnblogs.Architecture.Ddd.Infrastructure.MongoDb.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13-
<PackageReference Include="MongoDB.Driver" Version="3.4.2" />
13+
<PackageReference Include="MongoDB.Driver" Version="3.4.3" />
1414
</ItemGroup>
1515

1616
<ItemGroup>

test/Cnblogs.Architecture.IntegrationTests/Cnblogs.Architecture.IntegrationTests.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<ItemGroup>
33
<PackageReference Include="Cnblogs.Serilog.Extensions" Version="1.1.0" />
4-
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.3">
4+
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4">
55
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
66
<PrivateAssets>all</PrivateAssets>
77
</PackageReference>
88
<PackageReference Include="coverlet.collector" Version="6.0.4">
99
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1010
<PrivateAssets>all</PrivateAssets>
1111
</PackageReference>
12-
<PackageReference Include="Serilog.Sinks.InMemory" Version="0.16.0" />
12+
<PackageReference Include="Serilog.Sinks.InMemory" Version="2.0.0" />
1313
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
1414
<PackageReference Include="xunit" Version="2.9.3" />
1515
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />

test/Cnblogs.Architecture.UnitTests/Cnblogs.Architecture.UnitTests.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<ItemGroup>
44
<PackageReference Include="xunit" Version="2.9.3"/>
55
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1"/>
6-
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.3">
6+
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4">
77
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
88
<PrivateAssets>all</PrivateAssets>
99
</PackageReference>
@@ -15,6 +15,7 @@
1515
</ItemGroup>
1616

1717
<ItemGroup>
18+
<ProjectReference Include="..\..\src\Cnblogs.Architecture.Ddd.Cqrs.Dapper.Clickhouse\Cnblogs.Architecture.Ddd.Cqrs.Dapper.Clickhouse.csproj" />
1819
<ProjectReference Include="..\..\src\Cnblogs.Architecture.Ddd.Cqrs.EntityFramework\Cnblogs.Architecture.Ddd.Cqrs.EntityFramework.csproj"/>
1920
<ProjectReference Include="..\..\src\Cnblogs.Architecture.Ddd.Cqrs.MongoDb\Cnblogs.Architecture.Ddd.Cqrs.MongoDb.csproj"/>
2021
<ProjectReference Include="..\Cnblogs.Architecture.TestIntegrationEvents\Cnblogs.Architecture.TestIntegrationEvents.csproj"/>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using ClickHouse.Client;
2+
using Cnblogs.Architecture.Ddd.Cqrs.Dapper;
3+
using Cnblogs.Architecture.Ddd.Cqrs.Dapper.Clickhouse;
4+
using Microsoft.Extensions.DependencyInjection;
5+
6+
namespace Cnblogs.Architecture.UnitTests.Cqrs.Dapper;
7+
8+
public class ClickhouseDependencyInjectorTests
9+
{
10+
[Fact]
11+
public void UseClickhouse_InjectSingle_Injected()
12+
{
13+
// Arrange
14+
var services = new ServiceCollection();
15+
16+
// Act
17+
services.AddDapperContext<TestClickhouseDapperContext>().UseClickhouse("HOST=clickhouse");
18+
var serviceProvider = services.BuildServiceProvider();
19+
var dbContext = serviceProvider.GetRequiredService<TestClickhouseDapperContext>();
20+
var clickhouseDataSource =
21+
serviceProvider.GetRequiredKeyedService<IClickHouseDataSource>(nameof(TestClickhouseDapperContext));
22+
23+
// Assert
24+
Assert.NotNull(dbContext);
25+
Assert.NotNull(clickhouseDataSource);
26+
}
27+
28+
[Fact]
29+
public void UseClickhouse_InjectMultiple_Injected()
30+
{
31+
// Arrange
32+
var services = new ServiceCollection();
33+
34+
// Act
35+
services.AddDapperContext<TestClickhouseDapperContext>().UseClickhouse("HOST=clickhouse");
36+
services.AddDapperContext<TestAlterClickhouseDapperContext>().UseClickhouse("HOST=alterclickhouse");
37+
var serviceProvider = services.BuildServiceProvider();
38+
var dbContext = serviceProvider.GetRequiredService<TestClickhouseDapperContext>();
39+
var alterContext = serviceProvider.GetRequiredService<TestAlterClickhouseDapperContext>();
40+
var dbFactory = dbContext.Factory;
41+
var alterFactory = alterContext.Factory;
42+
43+
// Assert
44+
Assert.True(dbFactory is ClickhouseDbConnectionFactory<TestClickhouseDapperContext>);
45+
Assert.True(alterFactory is ClickhouseDbConnectionFactory<TestAlterClickhouseDapperContext>);
46+
}
47+
}

0 commit comments

Comments
 (0)