Skip to content

Commit 6bad178

Browse files
committed
fix import scope issue
1 parent 297bc33 commit 6bad178

File tree

2 files changed

+38
-32
lines changed

2 files changed

+38
-32
lines changed

src/FluentCommand.SqlServer/Import/ImportProcessor.cs

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Data;
3+
using System.Xml.Serialization;
34

45
using FluentCommand.Extensions;
56
using FluentCommand.Merge;
@@ -14,19 +15,17 @@ namespace FluentCommand.Import;
1415
public class ImportProcessor : IImportProcessor
1516
{
1617
private readonly IDataSession _dataSession;
17-
private readonly IServiceProvider _serviceProvider;
18-
19-
private IImportValidator _importValidator;
18+
private readonly IServiceScopeFactory _serviceScopeFactory;
2019

2120
/// <summary>
2221
/// Initializes a new instance of the <see cref="ImportProcessor"/> class.
2322
/// </summary>
2423
/// <param name="dataSession">The data session used for database operations.</param>
25-
/// <param name="serviceProvider">The service provider for resolving dependencies such as translators and validators.</param>
26-
public ImportProcessor(IDataSession dataSession, IServiceProvider serviceProvider)
24+
/// <param name="serviceScopeFactory">The service provider for resolving dependencies such as translators and validators.</param>
25+
public ImportProcessor(IDataSession dataSession, IServiceScopeFactory serviceScopeFactory)
2726
{
2827
_dataSession = dataSession;
29-
_serviceProvider = serviceProvider;
28+
_serviceScopeFactory = serviceScopeFactory;
3029
}
3130

3231
/// <summary>
@@ -48,24 +47,29 @@ public virtual async Task<ImportResult> ImportAsync(ImportDefinition importDefin
4847
if (importDefinition == null)
4948
throw new ArgumentNullException(nameof(importDefinition));
5049

51-
// validator is shared for entire import process
52-
_importValidator = GetValidator(importDefinition);
53-
54-
var context = new ImportProcessContext(_serviceProvider, importDefinition, importData, username);
50+
var scopedServices = _serviceScopeFactory.CreateScope();
51+
try
52+
{
53+
var context = new ImportProcessContext(scopedServices.ServiceProvider, importDefinition, importData, username);
5554

56-
var dataTable = CreateTable(context);
57-
await PopulateTable(context, dataTable);
55+
var dataTable = CreateTable(context);
56+
await PopulateTable(context, dataTable);
5857

59-
if (dataTable.Rows.Count == 0)
60-
return new ImportResult { Processed = 0, Errors = context.Errors?.ConvertAll(e => e.Message) };
58+
if (dataTable.Rows.Count == 0)
59+
return new ImportResult { Processed = 0, Errors = context.Errors?.ConvertAll(e => e.Message) };
6160

62-
var mergeDefinition = CreateMergeDefinition(context);
61+
var mergeDefinition = CreateMergeDefinition(context);
6362

64-
var result = await _dataSession
65-
.MergeData(mergeDefinition)
66-
.ExecuteAsync(dataTable, cancellationToken);
63+
var result = await _dataSession
64+
.MergeData(mergeDefinition)
65+
.ExecuteAsync(dataTable, cancellationToken);
6766

68-
return new ImportResult { Processed = result, Errors = context.Errors?.ConvertAll(e => e.Message) };
67+
return new ImportResult { Processed = result, Errors = context.Errors?.ConvertAll(e => e.Message) };
68+
}
69+
finally
70+
{
71+
scopedServices.Dispose();
72+
}
6973
}
7074

7175
/// <summary>
@@ -176,8 +180,9 @@ protected virtual async Task<bool> PopulateRow(ImportProcessContext importContex
176180
dataRow[field.Definition.Name] = convertValue ?? DBNull.Value;
177181
}
178182

179-
if (_importValidator != null)
180-
await _importValidator.ValidateRow(importContext.Definition, dataRow);
183+
var importValidator = GetValidator(importContext);
184+
if (importValidator != null)
185+
await importValidator.ValidateRow(importContext.Definition, dataRow);
181186

182187
return true;
183188
}
@@ -208,7 +213,7 @@ protected virtual async Task<object> ConvertValue(ImportProcessContext importCon
208213
#pragma warning disable CS0618 // Type or member is obsolete
209214
if (field.Translator != null)
210215
{
211-
if (_serviceProvider.GetService(field.Translator) is not IFieldTranslator translator)
216+
if (importContext.Services.GetService(field.Translator) is not IFieldTranslator translator)
212217
throw new InvalidOperationException($"Failed to create translator '{field.Translator}' for field '{field.Name}'");
213218

214219
return await translator.Translate(value);
@@ -217,7 +222,7 @@ protected virtual async Task<object> ConvertValue(ImportProcessContext importCon
217222

218223
if (field.TranslatorKey != null)
219224
{
220-
var translator = _serviceProvider.GetKeyedService<IFieldTranslator>(field.TranslatorKey);
225+
var translator = importContext.Services.GetKeyedService<IFieldTranslator>(field.TranslatorKey);
221226
if (translator == null)
222227
throw new InvalidOperationException($"Failed to create translator with service key '{field.TranslatorKey}' for field '{field.Name}'");
223228

@@ -290,24 +295,24 @@ protected virtual DataMergeDefinition CreateMergeDefinition(ImportProcessContext
290295
return mergeDefinition;
291296
}
292297

293-
protected virtual IImportValidator GetValidator(ImportDefinition importDefinition)
298+
protected virtual IImportValidator GetValidator(ImportProcessContext importContext)
294299
{
295300
#pragma warning disable CS0618 // Type or member is obsolete
296-
if (importDefinition.Validator != null)
301+
if (importContext.Definition.Validator != null)
297302
{
298-
var validator = _serviceProvider.GetService(importDefinition.Validator);
303+
var validator = importContext.Services.GetService(importContext.Definition.Validator);
299304
if (validator is not IImportValidator importValidator)
300-
throw new InvalidOperationException($"Failed to create data row validator '{importDefinition.Validator}'");
305+
throw new InvalidOperationException($"Failed to create data row validator '{importContext.Definition.Validator}'");
301306

302307
return importValidator;
303308
}
304309
#pragma warning restore CS0618 // Type or member is obsolete
305310

306-
if (importDefinition.ValidatorKey != null)
311+
if (importContext.Definition.ValidatorKey != null)
307312
{
308-
var validator = _serviceProvider.GetKeyedService<IImportValidator>(importDefinition.ValidatorKey);
313+
var validator = importContext.Services.GetKeyedService<IImportValidator>(importContext.Definition.ValidatorKey);
309314
if (validator == null)
310-
throw new InvalidOperationException($"Failed to create data row validator with service key '{importDefinition.ValidatorKey}'");
315+
throw new InvalidOperationException($"Failed to create data row validator with service key '{importContext.Definition.ValidatorKey}'");
311316

312317
return validator;
313318
}

src/FluentCommand.SqlServer/ImportServiceCollectionExtensions.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ public static class ImportServiceCollectionExtensions
2626
/// </remarks>
2727
public static IServiceCollection AddFluentImport(this IServiceCollection services)
2828
{
29-
services.TryAddTransient<ImportValidator>();
30-
services.TryAddKeyedTransient<IImportValidator, ImportValidator>(nameof(ImportValidator));
29+
// validator shared for import scope
30+
services.TryAddScoped<ImportValidator>();
31+
services.TryAddKeyedScoped<IImportValidator, ImportValidator>(nameof(ImportValidator));
3132

3233
services.TryAddTransient<IImportProcessor, ImportProcessor>();
3334

0 commit comments

Comments
 (0)