Skip to content

Commit 1c2f6ce

Browse files
committed
Make the generic version of SafeIDispatchWrapper visible only to Rubberduck.VBEditor and Rubberduck.VBEditor.* to ensure raw COM objects will not leak outside those projects.
Add comments describing the intended usage of both versions.
1 parent fdb782a commit 1c2f6ce

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
using System.Reflection;
2-
using System.Runtime.InteropServices;
1+
using System.Runtime.InteropServices;
32
using System.Runtime.CompilerServices;
43

54
[assembly: InternalsVisibleTo("RubberduckTests")]
65

6+
//Allow Rubberduck.VBEditor.* projects to use internal class
7+
[assembly: InternalsVisibleTo("Rubberduck.VBEditor.VB6")]
8+
[assembly: InternalsVisibleTo("Rubberduck.VBEditor.VBA")]
9+
710
// The following GUID is for the ID of the typelib if this project is exposed to COM
811
[assembly: Guid("4758424b-266e-4a3a-83c6-4aa50af7ea9e")]
912
[assembly: ComVisible(false)]

Rubberduck.VBEEditor/SafeComWrappers/SafeIDispatchWrapper.cs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,36 @@
44

55
namespace Rubberduck.VBEditor.SafeComWrappers
66
{
7-
public class SafeIDispatchWrapper<TDispatch> : SafeIDispatchWrapper
7+
/// <summary>
8+
/// Creates a new IDispatch-based wrapper for a provided
9+
/// COM interface. This is internal and should be used only
10+
/// within the Rubberduck.VBEditor.* projects.
11+
/// </summary>
12+
/// <remarks>
13+
/// To avoid exposing additional interop libraries to other projects
14+
/// and violating the separation, only the non-generic version of
15+
/// <see cref="SafeIDispatchWrapper" /> be provided for consumption outside
16+
/// the Rubberduck.VBEditor.* projects.
17+
/// Within those projects, the class is useful for wrapping COM interfaces
18+
/// that do not have a corresponding <see cref="ISafeComWrapper{T}" />
19+
/// implementations to ensure those are managed and will not leak.
20+
/// </remarks>
21+
/// <typeparam name="TDispatch">COM interface to wrap</typeparam>
22+
/// <inheritdoc />
23+
internal class SafeIDispatchWrapper<TDispatch> : SafeIDispatchWrapper
824
{
9-
public SafeIDispatchWrapper(TDispatch target, bool rewrapping = false) : base(target, rewrapping)
25+
internal SafeIDispatchWrapper(TDispatch target, bool rewrapping = false) : base(target, rewrapping)
1026
{ }
1127

1228
public new TDispatch Target => (TDispatch) base.Target;
1329
}
1430

31+
/// <summary>
32+
/// Provide a IDispatch-based (e.g. late-bound) access to a COM object.
33+
/// Use <see cref="Invoke"/> to work with the object. The
34+
/// <see cref="SafeIDispatchWrapper.Target"/> must be a raw COM object without
35+
/// any wrappers.
36+
/// </summary>
1537
public class SafeIDispatchWrapper : SafeComWrapper<dynamic>
1638
{
1739
public SafeIDispatchWrapper(object target, bool rewrapping = false) : base(target, rewrapping)
@@ -24,8 +46,18 @@ public SafeIDispatchWrapper(object target, bool rewrapping = false) : base(targe
2446
IDispatchPointer = GetPointer(target);
2547
}
2648

49+
// ReSharper disable once InconsistentNaming
2750
public IntPtr IDispatchPointer { get; }
2851

52+
/// <summary>
53+
/// Use the method to encapsulate operations against the late-bound COM object.
54+
/// It is caller's responsibilty to handle any exceptions that may result as part
55+
/// of the operation.
56+
/// </summary>
57+
/// <param name="action">
58+
/// A method that perform work against the late-bound COM object provided as the
59+
/// parameter to the function
60+
/// </param>
2961
public void Invoke(Action<dynamic> action)
3062
{
3163
action.Invoke(Target);

0 commit comments

Comments
 (0)