-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathMongoRunnerProvider.cs
93 lines (77 loc) · 2.77 KB
/
MongoRunnerProvider.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
using EphemeralMongo;
namespace TestBuildingBlocks;
// Based on https://gist.github.com/asimmon/612b2d54f1a0d2b4e1115590d456e0be.
internal sealed class MongoRunnerProvider
{
public static readonly MongoRunnerProvider Instance = new();
private readonly object _lockObject = new();
private IMongoRunner? _runner;
private int _useCounter;
private MongoRunnerProvider()
{
}
public IMongoRunner Get()
{
lock (_lockObject)
{
if (_runner == null)
{
var runnerOptions = new MongoRunnerOptions
{
// Single-node replica set mode is required for transaction support in MongoDB.
UseSingleNodeReplicaSet = true,
KillMongoProcessesWhenCurrentProcessExits = true,
AdditionalArguments = "--quiet"
};
_runner = MongoRunner.Run(runnerOptions);
}
_useCounter++;
return new MongoRunnerWrapper(this, _runner);
}
}
private void Detach()
{
lock (_lockObject)
{
if (_runner != null)
{
_useCounter--;
if (_useCounter == 0)
{
_runner.Dispose();
_runner = null;
}
}
}
}
private sealed class MongoRunnerWrapper(MongoRunnerProvider owner, IMongoRunner underlyingMongoRunner) : IMongoRunner
{
private readonly MongoRunnerProvider _owner = owner;
private IMongoRunner? _underlyingMongoRunner = underlyingMongoRunner;
public string ConnectionString => _underlyingMongoRunner?.ConnectionString ?? throw new ObjectDisposedException(nameof(IMongoRunner));
public void Import(string database, string collection, string inputFilePath, string? additionalArguments = null, bool drop = false)
{
if (_underlyingMongoRunner == null)
{
throw new ObjectDisposedException(nameof(IMongoRunner));
}
_underlyingMongoRunner.Import(database, collection, inputFilePath, additionalArguments, drop);
}
public void Export(string database, string collection, string outputFilePath, string? additionalArguments = null)
{
if (_underlyingMongoRunner == null)
{
throw new ObjectDisposedException(nameof(IMongoRunner));
}
_underlyingMongoRunner.Export(database, collection, outputFilePath, additionalArguments);
}
public void Dispose()
{
if (_underlyingMongoRunner != null)
{
_underlyingMongoRunner = null;
_owner.Detach();
}
}
}
}