Skip to content

Commit 00f0a6c

Browse files
committed
Added DisposalActionContainer.
1 parent dc17662 commit 00f0a6c

File tree

4 files changed

+91
-1
lines changed

4 files changed

+91
-1
lines changed

Rubberduck.VBEEditor/Rubberduck.VBEditor.csproj

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

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)