Skip to content

Commit 2d01027

Browse files
committed
Clean up memory leaks from the dockable presenters
1 parent 6230fa4 commit 2d01027

15 files changed

+78
-66
lines changed

RetailCoder.VBE/Inspections/IInspector.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace Rubberduck.Inspections
88
{
9-
public interface IInspector
9+
public interface IInspector : IDisposable
1010
{
1111
Task<IEnumerable<ICodeInspectionResult>> FindIssuesAsync(RubberduckParserState state, CancellationToken token);
1212
}

RetailCoder.VBE/Inspections/Inspector.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace Rubberduck.Inspections
1515
{
1616
namespace Rubberduck.Inspections
1717
{
18-
public class Inspector : IInspector, IDisposable
18+
public class Inspector : IInspector
1919
{
2020
private readonly IGeneralConfigService _configService;
2121
private readonly IEnumerable<IInspection> _inspections;

RetailCoder.VBE/Root/RubberduckModule.cs

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
using Ninject.Modules;
1010
using Rubberduck.Common;
1111
using Rubberduck.Inspections;
12-
using Rubberduck.Navigation.CodeExplorer;
1312
using Rubberduck.Parsing;
1413
using Rubberduck.Parsing.VBA;
1514
using Rubberduck.Settings;
@@ -31,6 +30,7 @@
3130
using Rubberduck.Parsing.Preprocessing;
3231
using System.Globalization;
3332
using Ninject.Extensions.Interception.Infrastructure.Language;
33+
using Ninject.Extensions.NamedScope;
3434
using Rubberduck.Parsing.Symbols;
3535
using Rubberduck.UI.CodeExplorer.Commands;
3636

@@ -96,53 +96,46 @@ public override void Load()
9696

9797
Bind<IPresenter>().To<TestExplorerDockablePresenter>()
9898
.WhenInjectedInto<TestExplorerCommand>()
99-
.InSingletonScope()
100-
.WithConstructorArgument<IDockableUserControl>(new TestExplorerWindow { ViewModel = Kernel.Get<TestExplorerViewModel>() });
99+
.InSingletonScope();
101100

102101
Bind<IPresenter>().To<CodeInspectionsDockablePresenter>()
103102
.WhenInjectedInto<InspectionResultsCommand>()
104-
.InSingletonScope()
105-
.WithConstructorArgument<IDockableUserControl>(new CodeInspectionsWindow { ViewModel = Kernel.Get<InspectionResultsViewModel>() });
103+
.InSingletonScope();
106104

107-
Bind<IControlView>().To<ChangesView>();
108-
Bind<IControlView>().To<BranchesView>();
109-
Bind<IControlView>().To<UnsyncedCommitsView>();
110-
Bind<IControlView>().To<SettingsView>();
105+
Bind<IControlView>().To<ChangesView>().InCallScope();
106+
Bind<IControlView>().To<BranchesView>().InCallScope();
107+
Bind<IControlView>().To<UnsyncedCommitsView>().InCallScope();
108+
Bind<IControlView>().To<SettingsView>().InCallScope();
111109

112110
Bind<IControlViewModel>().To<ChangesViewViewModel>()
113-
.WhenInjectedInto<ChangesView>();
111+
.WhenInjectedInto<ChangesView>().InCallScope();
114112
Bind<IControlViewModel>().To<BranchesViewViewModel>()
115-
.WhenInjectedInto<BranchesView>();
113+
.WhenInjectedInto<BranchesView>().InCallScope();
116114
Bind<IControlViewModel>().To<UnsyncedCommitsViewViewModel>()
117-
.WhenInjectedInto<UnsyncedCommitsView>();
115+
.WhenInjectedInto<UnsyncedCommitsView>().InCallScope();
118116
Bind<IControlViewModel>().To<SettingsViewViewModel>()
119-
.WhenInjectedInto<SettingsView>();
117+
.WhenInjectedInto<SettingsView>().InCallScope();
120118

121119
Bind<ISourceControlProviderFactory>().To<SourceControlProviderFactory>()
122120
.WhenInjectedInto<SourceControlViewViewModel>();
123121

124-
Bind<SourceControlDockablePresenter>().ToSelf()
125-
.InSingletonScope()
126-
.WithConstructorArgument(new SourceControlPanel { ViewModel = Kernel.Get<SourceControlViewViewModel>() });
122+
Bind<SourceControlDockablePresenter>().ToSelf().InSingletonScope();
127123

128124
BindCommandsToCodeExplorer();
129125
Bind<IPresenter>().To<CodeExplorerDockablePresenter>()
130126
.WhenInjectedInto<CodeExplorerCommand>()
131-
.InSingletonScope()
132-
.WithConstructorArgument<IDockableUserControl>(new CodeExplorerWindow { ViewModel = Kernel.Get<CodeExplorerViewModel>() });
127+
.InSingletonScope();
133128

134129
Bind<IPresenter>().To<ToDoExplorerDockablePresenter>()
135130
.WhenInjectedInto<ToDoExplorerCommand>()
136-
.InSingletonScope()
137-
.WithConstructorArgument<IDockableUserControl>(new ToDoExplorerWindow { ViewModel = Kernel.Get<ToDoExplorerViewModel>() });
131+
.InSingletonScope();
138132

139133
ConfigureRubberduckMenu();
140134
ConfigureCodePaneContextMenu();
141135
ConfigureFormDesignerContextMenu();
142136
ConfigureFormDesignerControlContextMenu();
143137
ConfigureProjectExplorerContextMenu();
144138

145-
146139
BindWindowsHooks();
147140
}
148141

@@ -164,7 +157,7 @@ private void ApplyDefaultInterfacesConvention(IEnumerable<Assembly> assemblies)
164157
// inspections & factories have their own binding rules
165158
.Where(type => !type.Name.EndsWith("Factory") && !type.Name.EndsWith("ConfigProvider") && !type.GetInterfaces().Contains(typeof(IInspection)))
166159
.BindDefaultInterface()
167-
.Configure(binding => binding.InThreadScope())); // TransientScope wouldn't dispose disposables
160+
.Configure(binding => binding.InCallScope())); // TransientScope wouldn't dispose disposables
168161
}
169162

170163
// note: settings namespace classes are injected in singleton scope
@@ -220,7 +213,7 @@ private void BindCodeInspectionTypes()
220213
{
221214
var binding = Bind<IParseTreeInspection>()
222215
.To(inspection)
223-
.InSingletonScope()
216+
.InCallScope()
224217
.Named(inspection.FullName);
225218

226219
binding.Intercept().With<TimedCallLoggerInterceptor>();
@@ -231,7 +224,7 @@ private void BindCodeInspectionTypes()
231224
}
232225
else
233226
{
234-
var binding = Bind<IInspection>().To(inspection).InSingletonScope();
227+
var binding = Bind<IInspection>().To(inspection).InCallScope();
235228
binding.Intercept().With<TimedCallLoggerInterceptor>();
236229
binding.Intercept().With<EnumerableCounterInterceptor<InspectionResultBase>>();
237230
}
@@ -296,7 +289,7 @@ private void BindParentMenuItem<TParentMenu>(CommandBarControls parent, int befo
296289
{
297290
Bind<IParentMenuItem>().To(typeof(TParentMenu))
298291
.WhenInjectedInto<IAppMenu>()
299-
.InThreadScope()
292+
.InCallScope()
300293
.WithConstructorArgument("items", items)
301294
.WithConstructorArgument("beforeIndex", beforeIndex)
302295
.WithPropertyValue("Parent", parent);

RetailCoder.VBE/Rubberduck.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,10 @@
253253
<HintPath>..\packages\Ninject.Extensions.Interception.DynamicProxy.3.2.0.0\lib\net45-full\Ninject.Extensions.Interception.DynamicProxy.dll</HintPath>
254254
<Private>True</Private>
255255
</Reference>
256+
<Reference Include="Ninject.Extensions.NamedScope, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
257+
<HintPath>..\packages\Ninject.Extensions.NamedScope.3.2.0.0\lib\net45-full\Ninject.Extensions.NamedScope.dll</HintPath>
258+
<Private>True</Private>
259+
</Reference>
256260
<Reference Include="PresentationCore" />
257261
<Reference Include="PresentationFramework" />
258262
<Reference Include="PresentationFramework.Aero" />
@@ -369,6 +373,7 @@
369373
<Compile Include="Inspections\MalformedAnnotationInspection.cs" />
370374
<Compile Include="Inspections\ObjectVariableNotSetInspection.cs" />
371375
<Compile Include="Inspections\RemoveExplicitCallStatmentQuickFix.cs" />
376+
<Compile Include="Inspections\WriteOnlyPropertyQuickFix.cs" />
372377
<Compile Include="Navigation\CodeExplorer\ICodeExplorerDeclarationViewModel.cs" />
373378
<Compile Include="Navigation\Folders\FolderHelper.cs" />
374379
<Compile Include="Refactorings\ExtractMethod\ExtractedMethod.cs" />

RetailCoder.VBE/UI/CodeExplorer/CodeExplorerDockablePresenter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public class CodeExplorerDockablePresenter : DockableToolwindowPresenter
66
{
77
private CodeExplorerWindow Control { get { return UserControl as CodeExplorerWindow; } }
88

9-
public CodeExplorerDockablePresenter(VBE vbe, AddIn addIn, IDockableUserControl view)
9+
public CodeExplorerDockablePresenter(VBE vbe, AddIn addIn, CodeExplorerWindow view)
1010
: base(vbe, addIn, view)
1111
{
1212
}

RetailCoder.VBE/UI/CodeExplorer/CodeExplorerWindow.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,21 @@ public partial class CodeExplorerWindow : UserControl, IDockableUserControl
1111
string IDockableUserControl.ClassId { get { return ClassId; } }
1212
string IDockableUserControl.Caption { get { return RubberduckUI.CodeExplorerDockablePresenter_Caption; } }
1313

14-
public CodeExplorerWindow()
14+
private CodeExplorerWindow()
1515
{
1616
InitializeComponent();
1717
}
1818

19-
private CodeExplorerViewModel _viewModel;
19+
public CodeExplorerWindow(CodeExplorerViewModel viewModel) : this()
20+
{
21+
_viewModel = viewModel;
22+
codeExplorerControl1.DataContext = _viewModel;
23+
}
24+
25+
private readonly CodeExplorerViewModel _viewModel;
2026
public CodeExplorerViewModel ViewModel
2127
{
2228
get { return _viewModel; }
23-
set
24-
{
25-
_viewModel = value;
26-
codeExplorerControl1.DataContext = _viewModel;
27-
}
2829
}
2930
}
3031
}

RetailCoder.VBE/UI/Inspections/CodeInspectionsDockablePresenter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace Rubberduck.UI.Inspections
44
{
55
public class CodeInspectionsDockablePresenter : DockableToolwindowPresenter
66
{
7-
public CodeInspectionsDockablePresenter(VBE vbe, AddIn addin, IDockableUserControl window)
7+
public CodeInspectionsDockablePresenter(VBE vbe, AddIn addin, CodeInspectionsWindow window)
88
:base(vbe, addin, window)
99
{
1010
}

RetailCoder.VBE/UI/Inspections/CodeInspectionsWindow.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,21 @@ public partial class CodeInspectionsWindow : UserControl, IDockableUserControl
88
string IDockableUserControl.ClassId { get { return ClassId; } }
99
string IDockableUserControl.Caption { get { return RubberduckUI.CodeInspections; } }
1010

11-
public CodeInspectionsWindow()
11+
private CodeInspectionsWindow()
1212
{
1313
InitializeComponent();
1414
}
1515

16-
private InspectionResultsViewModel _viewModel;
16+
public CodeInspectionsWindow(InspectionResultsViewModel viewModel) : this()
17+
{
18+
_viewModel = viewModel;
19+
wpfInspectionResultsControl.DataContext = _viewModel;
20+
}
21+
22+
private readonly InspectionResultsViewModel _viewModel;
1723
public InspectionResultsViewModel ViewModel
1824
{
1925
get { return _viewModel; }
20-
set
21-
{
22-
_viewModel = value;
23-
wpfInspectionResultsControl.DataContext = _viewModel;
24-
}
2526
}
2627
}
2728
}

RetailCoder.VBE/UI/Inspections/InspectionResultsViewModel.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,11 @@ public void Dispose()
469469
{
470470
_configService.SettingsChanged -= _configService_SettingsChanged;
471471
}
472+
473+
if (_inspector != null)
474+
{
475+
_inspector.Dispose();
476+
}
472477
}
473478
}
474479
}

RetailCoder.VBE/UI/SourceControl/SourceControlPanel.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,17 @@ namespace Rubberduck.UI.SourceControl
66
[ExcludeFromCodeCoverage]
77
public partial class SourceControlPanel : UserControl, IDockableUserControl
88
{
9-
public SourceControlPanel()
9+
private SourceControlPanel()
1010
{
1111
InitializeComponent();
1212
}
1313

14+
public SourceControlPanel(SourceControlViewViewModel viewModel) : this()
15+
{
16+
_viewModel = viewModel;
17+
SourceControlPanelControl.DataContext = viewModel;
18+
}
19+
1420
public string ClassId
1521
{
1622
get { return "19A32FC9-4902-4385-9FE7-829D4F9C441D"; }
@@ -21,10 +27,10 @@ public string Caption
2127
get { return RubberduckUI.SourceControlPanel_Caption; }
2228
}
2329

24-
public ViewModelBase ViewModel
30+
private readonly SourceControlViewViewModel _viewModel;
31+
public SourceControlViewViewModel ViewModel
2532
{
26-
get { return (SourceControlViewViewModel)SourceControlPanelControl.DataContext; }
27-
set { SourceControlPanelControl.DataContext = value; }
33+
get { return _viewModel; }
2834
}
2935
}
3036
}

0 commit comments

Comments
 (0)