-
Notifications
You must be signed in to change notification settings - Fork 0
/
GenericService.cs
163 lines (148 loc) · 5.54 KB
/
GenericService.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
using System;
using System.Collections.Generic;
using System.Data;
using System.Threading;
using System.Threading.Tasks;
namespace Dapper.Issue2117.Test;
public interface IGenericService<TEntity, TKey>
{
Task<TEntity> GetAsync(TKey id, CancellationToken token, bool commit = true);
Task<IEnumerable<TEntity>> GetAsync(CancellationToken token, bool commit = true);
Task<IEnumerable<TEntity>> GetAsync(int pageSize, int pageNo, CancellationToken token, bool commit = true);
Task<IEnumerable<TEntity>> GetAsync(IEnumerable<TEntity> filter, CancellationToken token, bool commit = true);
Task<TEntity> AddAsync(TEntity entity, CancellationToken token, bool commit = true);
Task<IEnumerable<TEntity>> AddAsync(IEnumerable<TEntity> entities, CancellationToken token, bool commit = true);
Task<TEntity> UpdateAsync(TEntity entity, CancellationToken token, bool commit = true);
Task<IEnumerable<TEntity>> UpdateAsync(IEnumerable<TEntity> entities, CancellationToken token, bool commit = true);
Task DeleteAsync(TEntity entity, CancellationToken token, bool commit = true);
Task DeleteAsync(IEnumerable<TEntity> entities, CancellationToken token, bool commit = true);
}
public abstract class GenericService<IRepository, TEntity, TKey> : IGenericService<TEntity, TKey> where IRepository: IGenericRepository<TEntity, TKey> where TEntity : class, new()
{
protected readonly IDatabaseConnectionFactory _connectionFactory;
protected readonly IRepository _repository;
protected GenericService(
IDatabaseConnectionFactory connectionFactory,
IRepository repository)
{
_connectionFactory = connectionFactory;
_repository = repository;
}
protected async Task<TResult> TransactionAsync<TResult>(Func<IDbTransaction, Task<TResult>> call,
IsolationLevel isolationLevel = IsolationLevel.ReadCommitted, bool commit = true)
{
using var connection = await _connectionFactory.CreateConnectionAsync();
using var transaction = connection.BeginTransaction(isolationLevel);
try
{
TResult result = await call(transaction);
if (commit)
transaction.Commit();
else
transaction.Rollback();
return result;
}
catch (Exception e)
{
transaction.Rollback();
throw;
}
}
protected async Task TransactionAsync(Func<IDbTransaction, Task> call,
IsolationLevel isolationLevel = IsolationLevel.ReadCommitted, bool commit = true)
{
using var connection = await _connectionFactory.CreateConnectionAsync();
using var transaction = connection.BeginTransaction(isolationLevel);
try
{
await call(transaction);
if (commit)
transaction.Commit();
else
transaction.Rollback();
}
catch (Exception e)
{
transaction.Rollback();
throw;
}
}
public virtual async Task<TEntity> GetAsync(TKey id, CancellationToken token, bool commit = true)
{
return await TransactionAsync(async tx =>
{
return await _repository.GetAsync(id, tx, token).ConfigureAwait(false);
}, commit:commit).ConfigureAwait(false);
}
public virtual async Task<IEnumerable<TEntity>> GetAsync(CancellationToken token, bool commit = true)
{
return await TransactionAsync(async tx =>
{
return await _repository.GetAsync(tx, token).ConfigureAwait(false);
}, commit:commit).ConfigureAwait(false);
}
public virtual async Task<IEnumerable<TEntity>> GetAsync(int pageSize, int pageNo,
CancellationToken token, bool commit = true)
{
return await TransactionAsync(async tx =>
{
return await _repository.GetAsync(pageSize, pageNo, tx, token).ConfigureAwait(false);
}, commit:commit).ConfigureAwait(false);
}
public virtual async Task<IEnumerable<TEntity>> GetAsync(IEnumerable<TEntity> filter,
CancellationToken token, bool commit = true)
{
return await TransactionAsync(async tx =>
{
return await _repository.GetAsync(filter, tx, token).ConfigureAwait(false);
}, commit:commit).ConfigureAwait(false);
}
public virtual async Task<TEntity> AddAsync(TEntity entity,
CancellationToken token, bool commit = true)
{
return await TransactionAsync(async tx =>
{
return await _repository.AddAsync(entity, tx, token).ConfigureAwait(false);
}, commit:commit).ConfigureAwait(false);
}
public virtual async Task<IEnumerable<TEntity>> AddAsync(IEnumerable<TEntity> entities,
CancellationToken token, bool commit = true)
{
return await TransactionAsync(async tx =>
{
return await _repository.AddAsync(entities, tx, token).ConfigureAwait(false);
}, commit:commit).ConfigureAwait(false);
}
public virtual async Task<TEntity> UpdateAsync(TEntity entity,
CancellationToken token, bool commit = true)
{
return await TransactionAsync(async tx =>
{
return await _repository.UpdateAsync(entity, tx, token).ConfigureAwait(false);
}, commit:commit).ConfigureAwait(false);
}
public virtual async Task<IEnumerable<TEntity>> UpdateAsync(IEnumerable<TEntity> entities,
CancellationToken token, bool commit = true)
{
return await TransactionAsync(async tx =>
{
return await _repository.UpdateAsync(entities, tx, token).ConfigureAwait(false);
}, commit:commit).ConfigureAwait(false);
}
public virtual async Task DeleteAsync(TEntity entity,
CancellationToken token, bool commit = true)
{
await TransactionAsync(async tx =>
{
await _repository.DeleteAsync(entity, tx, token).ConfigureAwait(false);
}, commit:commit).ConfigureAwait(false);
}
public virtual async Task DeleteAsync(IEnumerable<TEntity> entities,
CancellationToken token, bool commit = true)
{
await TransactionAsync(async tx =>
{
await _repository.DeleteAsync(entities, tx, token).ConfigureAwait(false);
}, commit:commit).ConfigureAwait(false);
}
}