Skip to content

Commit fafe407

Browse files
authored
Merge pull request #3811 from MDoerner/IntroducingDisposalActionContainer
DisposalActionContainer (no user-facing changes)
2 parents 4f3efa4 + c74a87a commit fafe407

File tree

4 files changed

+96
-1
lines changed

4 files changed

+96
-1
lines changed

Rubberduck.VBEEditor/Rubberduck.VBEditor.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@
262262
<Compile Include="SafeComWrappers\MSForms\WindowState.cs" />
263263
<Compile Include="SafeComWrappers\SafeComWrapper.cs" />
264264
<Compile Include="SafeComWrappers\VBA\VBE.cs" />
265+
<Compile Include="Utility\DisposalActionContainer.cs" />
265266
<Compile Include="WindowsApi\ChildWindowFinder.cs" />
266267
<Compile Include="WindowsApi\CodePaneSubclass.cs" />
267268
<Compile Include="WindowsApi\DesignerWindowSubclass.cs" />
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
3+
namespace Rubberduck.VBEditor.Utility
4+
{
5+
public interface IDisposalActionContainer<out T>: IDisposable
6+
{
7+
T Value { get; }
8+
}
9+
10+
internal sealed class DisposalActionContainer<T> : IDisposalActionContainer<T>
11+
{
12+
public T Value { get; }
13+
private readonly Action _disposalAction;
14+
15+
public DisposalActionContainer(T value, Action disposalAction)
16+
{
17+
Value = value;
18+
_disposalAction = disposalAction;
19+
}
20+
21+
private bool _isDisposed = false;
22+
private readonly object _disposalLockObject = new object();
23+
public void Dispose()
24+
{
25+
lock (_disposalLockObject)
26+
{
27+
if (_isDisposed)
28+
{
29+
return;
30+
}
31+
_isDisposed = true;
32+
}
33+
34+
_disposalAction.Invoke();
35+
}
36+
}
37+
38+
public static class DisposalActionContainer
39+
{
40+
public static IDisposalActionContainer<T> Create<T>(T value, Action disposalAction)
41+
{
42+
return new DisposalActionContainer<T>(value, disposalAction);
43+
}
44+
}
45+
}

RubberduckTests/RubberduckTests.csproj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
<Compile Include="Mocks\MockExtentions.cs" />
109109
<Compile Include="Inspections\DefTypeStatementInspectionTests.cs" />
110110
<Compile Include="Inspections\InspectionProviderTests.cs" />
111+
<Compile Include="VBEditor\Utility\DisposalActionContainerTests.cs" />
111112
<Compile Include="VBEditor\ComSafeManagerTests.cs" />
112113
<Compile Include="VBEditor\ProjectsRepositoryTests.cs" />
113114
<Compile Include="VBEditor\ReferenceEqualityComparerTests.cs" />
@@ -346,7 +347,9 @@
346347
<Name>Rubberduck.VBEditor</Name>
347348
</ProjectReference>
348349
</ItemGroup>
349-
<ItemGroup />
350+
<ItemGroup>
351+
<Folder Include="Utility\" />
352+
</ItemGroup>
350353
<ItemGroup>
351354
<None Include="IntegrationTests\FakeTests.bas" />
352355
<None Include="IntegrationTests\StubTests.bas" />
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using NUnit.Framework;
2+
using Rubberduck.VBEditor.Utility;
3+
4+
namespace RubberduckTests.VBEditor.Utility
5+
{
6+
[TestFixture()]
7+
public class DisposalActionContainerTests
8+
{
9+
[Test()]
10+
public void ValueReturnsValuePassedIn()
11+
{
12+
var testValue = 42;
13+
var dac = DisposalActionContainer.Create(testValue, () => { });
14+
var returnedValue = dac.Value;
15+
16+
Assert.AreEqual(testValue, returnedValue);
17+
}
18+
19+
[Test()]
20+
public void FirstDisposeTriggersActionPassedIn()
21+
{
22+
var useCount = 0;
23+
var dac = DisposalActionContainer.Create(42, () => useCount++);
24+
dac.Dispose();
25+
var expectedUseCount = 1;
26+
27+
Assert.AreEqual(expectedUseCount, useCount);
28+
}
29+
30+
[Test()]
31+
public void MultipleCallsOfDisposeTriggerTheActionPassedInOnce()
32+
{
33+
var useCount = 0;
34+
var dac = DisposalActionContainer.Create(42, () => useCount++);
35+
dac.Dispose();
36+
dac.Dispose();
37+
dac.Dispose();
38+
dac.Dispose();
39+
dac.Dispose();
40+
dac.Dispose();
41+
var expectedUseCount = 1;
42+
43+
Assert.AreEqual(expectedUseCount, useCount);
44+
}
45+
}
46+
}

0 commit comments

Comments
 (0)