Skip to content

Commit 18a3a39

Browse files
committed
(#121) Distributed Lock
1 parent 789f7d9 commit 18a3a39

File tree

5 files changed

+41
-4
lines changed

5 files changed

+41
-4
lines changed

src/Monolith/ClassifiedAds.Application/EmailMessages/Services/EmailMessageService.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using ClassifiedAds.CrossCuttingConcerns.CircuitBreakers;
2+
using ClassifiedAds.CrossCuttingConcerns.Locks;
23
using ClassifiedAds.CrossCuttingConcerns.OS;
34
using ClassifiedAds.Domain.Notification;
45
using ClassifiedAds.Domain.Repositories;
@@ -17,18 +18,21 @@ public class EmailMessageService
1718
private readonly IEmailNotification _emailNotification;
1819
private readonly IDateTimeProvider _dateTimeProvider;
1920
private readonly ICircuitBreakerManager _circuitBreakerManager;
21+
private readonly IDistributedLock _distributedLock;
2022

2123
public EmailMessageService(ILogger<EmailMessageService> logger,
2224
IEmailMessageRepository repository,
2325
IEmailNotification emailNotification,
2426
IDateTimeProvider dateTimeProvider,
25-
ICircuitBreakerManager circuitBreakerManager)
27+
ICircuitBreakerManager circuitBreakerManager,
28+
IDistributedLock distributedLock)
2629
{
2730
_logger = logger;
2831
_repository = repository;
2932
_emailNotification = emailNotification;
3033
_dateTimeProvider = dateTimeProvider;
3134
_circuitBreakerManager = circuitBreakerManager;
35+
_distributedLock = distributedLock;
3236
}
3337

3438
public async Task<int> SendEmailMessagesAsync()

src/Monolith/ClassifiedAds.Application/SmsMessages/Services/SmsMessageService.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using ClassifiedAds.CrossCuttingConcerns.CircuitBreakers;
2+
using ClassifiedAds.CrossCuttingConcerns.Locks;
23
using ClassifiedAds.CrossCuttingConcerns.OS;
34
using ClassifiedAds.Domain.Notification;
45
using ClassifiedAds.Domain.Repositories;
@@ -17,18 +18,21 @@ public class SmsMessageService
1718
private readonly ISmsNotification _smsNotification;
1819
private readonly IDateTimeProvider _dateTimeProvider;
1920
private readonly ICircuitBreakerManager _circuitBreakerManager;
21+
private readonly IDistributedLock _distributedLock;
2022

2123
public SmsMessageService(ILogger<SmsMessageService> logger,
2224
ISmsMessageRepository repository,
2325
ISmsNotification smsNotification,
2426
IDateTimeProvider dateTimeProvider,
25-
ICircuitBreakerManager circuitBreakerManager)
27+
ICircuitBreakerManager circuitBreakerManager,
28+
IDistributedLock distributedLock)
2629
{
2730
_logger = logger;
2831
_repository = repository;
2932
_smsNotification = smsNotification;
3033
_dateTimeProvider = dateTimeProvider;
3134
_circuitBreakerManager = circuitBreakerManager;
35+
_distributedLock = distributedLock;
3236
}
3337

3438
public async Task<int> SendSmsMessagesAsync()

src/Monolith/ClassifiedAds.CrossCuttingConcerns/Locks/IDistributedLock.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
namespace ClassifiedAds.CrossCuttingConcerns.Locks
1+
using System;
2+
3+
namespace ClassifiedAds.CrossCuttingConcerns.Locks
24
{
3-
public interface IDistributedLock
5+
public interface IDistributedLock : IDisposable
46
{
57
IDistributedLockScope Acquire(string lockName);
68

src/Monolith/ClassifiedAds.Persistence/Locks/SqlDistributedLock.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using ClassifiedAds.CrossCuttingConcerns.Locks;
2+
using EntityFrameworkCore.SqlServer.SimpleBulks.Extensions;
23
using Microsoft.Data.SqlClient;
34
using System;
45
using System.Data;
@@ -11,6 +12,7 @@ public class SqlDistributedLock : IDistributedLock
1112

1213
private readonly SqlConnection _connection;
1314
private readonly SqlTransaction _transaction;
15+
private readonly string _connectionString;
1416

1517
public bool HasTransaction
1618
{
@@ -31,6 +33,12 @@ public SqlDistributedLock(SqlTransaction transaction)
3133
_connection = _transaction.Connection;
3234
}
3335

36+
public SqlDistributedLock(string connectionString)
37+
{
38+
_connectionString = connectionString;
39+
_connection = new SqlConnection(connectionString);
40+
}
41+
3442
public IDistributedLockScope Acquire(string lockName)
3543
{
3644
SqlParameter returnValue;
@@ -67,6 +75,8 @@ public IDistributedLockScope TryAcquire(string lockName)
6775

6876
private SqlCommand CreateAcquireCommand(int commandTimeout, string lockName, int lockTimeout, out SqlParameter returnValue)
6977
{
78+
_connection.EnsureOpen();
79+
7080
SqlCommand command = _connection.CreateCommand();
7181
command.Transaction = _transaction;
7282

@@ -120,5 +130,13 @@ public static bool ParseReturnCode(int returnCode)
120130

121131
return false;
122132
}
133+
134+
public void Dispose()
135+
{
136+
if (!string.IsNullOrEmpty(_connectionString))
137+
{
138+
_connection.Dispose();
139+
}
140+
}
123141
}
124142
}

src/Monolith/ClassifiedAds.Persistence/PersistenceExtensions.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ public static IServiceCollection AddPersistence(this IServiceCollection services
2525
}))
2626
.AddDbContextFactory<AdsDbContext>((Action<DbContextOptionsBuilder>)null, ServiceLifetime.Scoped)
2727
.AddRepositories();
28+
29+
services.AddScoped(typeof(IDistributedLock), _ => new SqlDistributedLock(connectionString));
30+
2831
return services;
2932
}
3033

@@ -39,6 +42,12 @@ public static IServiceCollection AddMultiTenantPersistence(this IServiceCollecti
3942
return services.GetRequiredService<AdsDbContextMultiTenant>();
4043
})
4144
.AddRepositories();
45+
46+
services.AddScoped(typeof(IDistributedLock), services =>
47+
{
48+
return new SqlDistributedLock(services.GetRequiredService<IConnectionStringResolver<AdsDbContextMultiTenant>>().ConnectionString);
49+
});
50+
4251
return services;
4352
}
4453

0 commit comments

Comments
 (0)