Skip to content

Commit 52d6474

Browse files
committed
Add caching to XmlPersistanceService, rebind providers as singleton.
1 parent 19965a9 commit 52d6474

File tree

10 files changed

+137
-41
lines changed

10 files changed

+137
-41
lines changed

RetailCoder.VBE/Root/RubberduckModule.cs

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
using Ninject.Extensions.Interception.Infrastructure.Language;
3131
using Ninject.Extensions.NamedScope;
3232
using Rubberduck.Inspections.Abstract;
33-
using Rubberduck.Parsing.Symbols;
3433
using Rubberduck.UI.CodeExplorer.Commands;
3534
using Rubberduck.UI.Command.MenuItems.CommandBars;
3635
using Rubberduck.VBEditor.Application;
@@ -191,17 +190,17 @@ private void ApplyConfigurationConvention(IEnumerable<Assembly> assemblies)
191190

192191
Bind<IPersistable<SerializableProject>>().To<XmlPersistableDeclarations>().InCallScope();
193192

194-
Bind<IPersistanceService<CodeInspectionSettings>>().To<XmlPersistanceService<CodeInspectionSettings>>().InCallScope();
195-
Bind<IPersistanceService<GeneralSettings>>().To<XmlPersistanceService<GeneralSettings>>().InCallScope();
196-
Bind<IPersistanceService<HotkeySettings>>().To<XmlPersistanceService<HotkeySettings>>().InCallScope();
197-
Bind<IPersistanceService<ToDoListSettings>>().To<XmlPersistanceService<ToDoListSettings>>().InCallScope();
198-
Bind<IPersistanceService<UnitTestSettings>>().To<XmlPersistanceService<UnitTestSettings>>().InCallScope();
199-
Bind<IPersistanceService<WindowSettings>>().To<XmlPersistanceService<WindowSettings>>().InCallScope();
200-
Bind<IPersistanceService<IndenterSettings>>().To<XmlPersistanceService<IndenterSettings>>().InCallScope();
201-
Bind<IFilePersistanceService<SourceControlSettings>>().To<XmlPersistanceService<SourceControlSettings>>().InCallScope();
193+
Bind<IPersistanceService<CodeInspectionSettings>>().To<XmlPersistanceService<CodeInspectionSettings>>().InSingletonScope();
194+
Bind<IPersistanceService<GeneralSettings>>().To<XmlPersistanceService<GeneralSettings>>().InSingletonScope();
195+
Bind<IPersistanceService<HotkeySettings>>().To<XmlPersistanceService<HotkeySettings>>().InSingletonScope();
196+
Bind<IPersistanceService<ToDoListSettings>>().To<XmlPersistanceService<ToDoListSettings>>().InSingletonScope();
197+
Bind<IPersistanceService<UnitTestSettings>>().To<XmlPersistanceService<UnitTestSettings>>().InSingletonScope();
198+
Bind<IPersistanceService<WindowSettings>>().To<XmlPersistanceService<WindowSettings>>().InSingletonScope();
199+
Bind<IPersistanceService<IndenterSettings>>().To<XmlPersistanceService<IndenterSettings>>().InSingletonScope();
200+
Bind<IFilePersistanceService<SourceControlSettings>>().To<XmlPersistanceService<SourceControlSettings>>().InSingletonScope();
202201

203-
Bind<IConfigProvider<IndenterSettings>>().To<IndenterConfigProvider>().InCallScope();
204-
Bind<IConfigProvider<SourceControlSettings>>().To<SourceControlConfigProvider>().InCallScope();
202+
Bind<IConfigProvider<IndenterSettings>>().To<IndenterConfigProvider>().InSingletonScope();
203+
Bind<IConfigProvider<SourceControlSettings>>().To<SourceControlConfigProvider>().InSingletonScope();
205204

206205
Bind<ICodeInspectionSettings>().To<CodeInspectionSettings>().InCallScope();
207206
Bind<IGeneralSettings>().To<GeneralSettings>().InCallScope();
@@ -434,7 +433,7 @@ private IEnumerable<IMenuItem> GetRubberduckMenuItems()
434433
GetSmartIndenterParentMenu(),
435434
GetToolsParentMenu(),
436435
GetRefactoringsParentMenu(),
437-
GetNavigateParentMenu(),
436+
GetNavigateParentMenu()
438437
};
439438
}
440439

@@ -446,7 +445,7 @@ private IMenuItem GetUnitTestingParentMenu()
446445
KernelInstance.Get<TestExplorerCommandMenuItem>(),
447446
KernelInstance.Get<AddTestModuleCommandMenuItem>(),
448447
KernelInstance.Get<AddTestMethodCommandMenuItem>(),
449-
KernelInstance.Get<AddTestMethodExpectedErrorCommandMenuItem>(),
448+
KernelInstance.Get<AddTestMethodExpectedErrorCommandMenuItem>()
450449
};
451450
return new UnitTestingParentMenu(items);
452451
}
@@ -477,7 +476,7 @@ private IMenuItem GetNavigateParentMenu()
477476
//KernelInstance.Get<RegexSearchReplaceCommandMenuItem>(),
478477
KernelInstance.Get<FindSymbolCommandMenuItem>(),
479478
KernelInstance.Get<FindAllReferencesCommandMenuItem>(),
480-
KernelInstance.Get<FindAllImplementationsCommandMenuItem>(),
479+
KernelInstance.Get<FindAllImplementationsCommandMenuItem>()
481480
};
482481
return new NavigateParentMenu(items);
483482
}
@@ -502,7 +501,7 @@ private IEnumerable<IMenuItem> GetCodePaneContextMenuItems()
502501
GetSmartIndenterParentMenu(),
503502
KernelInstance.Get<FindSymbolCommandMenuItem>(),
504503
KernelInstance.Get<FindAllReferencesCommandMenuItem>(),
505-
KernelInstance.Get<FindAllImplementationsCommandMenuItem>(),
504+
KernelInstance.Get<FindAllImplementationsCommandMenuItem>()
506505
};
507506
}
508507

@@ -512,7 +511,7 @@ private IMenuItem GetToolsParentMenu()
512511
{
513512
KernelInstance.Get<ShowSourceControlPanelCommandMenuItem>(),
514513
KernelInstance.Get<RegexAssistantCommandMenuItem>(),
515-
KernelInstance.Get<ToDoExplorerCommandMenuItem>(),
514+
KernelInstance.Get<ToDoExplorerCommandMenuItem>()
516515
};
517516

518517
return new ToolsParentMenu(items);
@@ -522,7 +521,7 @@ private IEnumerable<IMenuItem> GetFormDesignerContextMenuItems()
522521
{
523522
return new IMenuItem[]
524523
{
525-
KernelInstance.Get<FormDesignerRefactorRenameCommandMenuItem>(),
524+
KernelInstance.Get<FormDesignerRefactorRenameCommandMenuItem>()
526525
};
527526
}
528527

@@ -533,7 +532,7 @@ private IEnumerable<IMenuItem> GetProjectWindowContextMenuItems()
533532
KernelInstance.Get<ProjectExplorerRefactorRenameCommandMenuItem>(),
534533
KernelInstance.Get<FindSymbolCommandMenuItem>(),
535534
KernelInstance.Get<FindAllReferencesCommandMenuItem>(),
536-
KernelInstance.Get<FindAllImplementationsCommandMenuItem>(),
535+
KernelInstance.Get<FindAllImplementationsCommandMenuItem>()
537536
};
538537
}
539538
}

RetailCoder.VBE/Settings/CodeInspectionSettings.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Globalization;
34
using System.Linq;
45
using System.Xml.Serialization;
56
using Rubberduck.Inspections.Abstract;
@@ -16,7 +17,7 @@ public interface ICodeInspectionSettings
1617
}
1718

1819
[XmlType(AnonymousType = true)]
19-
public class CodeInspectionSettings : ICodeInspectionSettings
20+
public class CodeInspectionSettings : ICodeInspectionSettings, IEquatable<CodeInspectionSettings>
2021
{
2122
[XmlArrayItem("CodeInspection", IsNullable = false)]
2223
public HashSet<CodeInspectionSetting> CodeInspections { get; set; }
@@ -39,7 +40,7 @@ public CodeInspectionSettings(HashSet<CodeInspectionSetting> inspections, Whitel
3940

4041
public CodeInspectionSetting GetSetting<TInspection>() where TInspection : IInspection
4142
{
42-
return CodeInspections.FirstOrDefault(s => typeof(TInspection).Name.ToString().Equals(s.Name))
43+
return CodeInspections.FirstOrDefault(s => typeof(TInspection).Name.ToString(CultureInfo.InvariantCulture).Equals(s.Name))
4344
?? GetSetting(typeof(TInspection));
4445
}
4546

@@ -59,6 +60,14 @@ public CodeInspectionSetting GetSetting(Type inspection)
5960
return null;
6061
}
6162
}
63+
64+
public bool Equals(CodeInspectionSettings other)
65+
{
66+
return other != null &&
67+
CodeInspections.SequenceEqual(other.CodeInspections) &&
68+
WhitelistedIdentifiers.SequenceEqual(other.WhitelistedIdentifiers) &&
69+
RunInspectionsOnSuccessfulParse == other.RunInspectionsOnSuccessfulParse;
70+
}
6271
}
6372

6473
[XmlType(AnonymousType = true)]

RetailCoder.VBE/Settings/GeneralSettings.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace Rubberduck.Settings
77
{
8-
public interface IGeneralSettings
8+
public interface IGeneralSettings
99
{
1010
DisplayLanguageSetting Language { get; set; }
1111
bool ShowSplash { get; set; }
@@ -17,7 +17,7 @@ public interface IGeneralSettings
1717
}
1818

1919
[XmlType(AnonymousType = true)]
20-
public class GeneralSettings : IGeneralSettings
20+
public class GeneralSettings : IGeneralSettings, IEquatable<GeneralSettings>
2121
{
2222
public DisplayLanguageSetting Language { get; set; }
2323
public bool ShowSplash { get; set; }
@@ -57,5 +57,17 @@ public GeneralSettings()
5757
Delimiter = '.';
5858
MinimumLogLevel = LogLevel.Off.Ordinal;
5959
}
60+
61+
public bool Equals(GeneralSettings other)
62+
{
63+
return other != null &&
64+
Language.Equals(other.Language) &&
65+
ShowSplash == other.ShowSplash &&
66+
SmartIndenterPrompted == other.SmartIndenterPrompted &&
67+
AutoSaveEnabled == other.AutoSaveEnabled &&
68+
AutoSavePeriod == other.AutoSavePeriod &&
69+
Delimiter.Equals(other.Delimiter) &&
70+
MinimumLogLevel == other.MinimumLogLevel;
71+
}
6072
}
6173
}

RetailCoder.VBE/Settings/HotkeySettings.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public interface IHotkeySettings
1010
HotkeySetting[] Settings { get; set; }
1111
}
1212

13-
public class HotkeySettings : IHotkeySettings
13+
public class HotkeySettings : IHotkeySettings, IEquatable<HotkeySettings>
1414
{
1515
private static readonly HotkeySetting[] Defaults =
1616
{
@@ -79,6 +79,11 @@ private bool IsDuplicate(HotkeySetting candidate)
7979
s.HasShiftModifier == candidate.HasShiftModifier) != null;
8080
}
8181

82+
public bool Equals(HotkeySettings other)
83+
{
84+
return other != null && Settings.SequenceEqual(other.Settings);
85+
}
86+
8287
private static bool IsValid(HotkeySetting candidate)
8388
{
8489
//This feels a bit sleazy...

RetailCoder.VBE/Settings/ToDoListSettings.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using System.Linq;
34
using System.Xml.Serialization;
45
using Rubberduck.UI;
@@ -11,7 +12,7 @@ interface IToDoListSettings
1112
}
1213

1314
[XmlType(AnonymousType = true)]
14-
public class ToDoListSettings : IToDoListSettings
15+
public class ToDoListSettings : IToDoListSettings, IEquatable<ToDoListSettings>
1516
{
1617
private IEnumerable<ToDoMarker> _markers;
1718

@@ -39,5 +40,10 @@ public ToDoListSettings(IEnumerable<ToDoMarker> markers)
3940
{
4041
_markers = markers;
4142
}
43+
44+
public bool Equals(ToDoListSettings other)
45+
{
46+
return other != null && ToDoMarkers.SequenceEqual(other.ToDoMarkers);
47+
}
4248
}
4349
}

RetailCoder.VBE/Settings/UnitTestSettings.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Xml.Serialization;
1+
using System;
2+
using System.Xml.Serialization;
23

34
namespace Rubberduck.Settings
45
{
@@ -25,7 +26,7 @@ public interface IUnitTestSettings
2526
}
2627

2728
[XmlType(AnonymousType = true)]
28-
public class UnitTestSettings : IUnitTestSettings
29+
public class UnitTestSettings : IUnitTestSettings, IEquatable<UnitTestSettings>
2930
{
3031
public UnitTestSettings()
3132
: this(BindingMode.LateBinding, AssertMode.StrictAssert, true, true, false)
@@ -47,5 +48,15 @@ public UnitTestSettings(BindingMode bindingMode, AssertMode assertMode, bool mod
4748
public bool ModuleInit { get; set; }
4849
public bool MethodInit { get; set; }
4950
public bool DefaultTestStubInNewModule { get; set; }
51+
52+
public bool Equals(UnitTestSettings other)
53+
{
54+
return other != null &&
55+
BindingMode == other.BindingMode &&
56+
AssertMode == other.AssertMode &&
57+
ModuleInit == other.ModuleInit &&
58+
MethodInit == other.MethodInit &&
59+
DefaultTestStubInNewModule == other.DefaultTestStubInNewModule;
60+
}
5061
}
5162
}

RetailCoder.VBE/Settings/WindowSettings.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
using System.Xml.Serialization;
2-
using Rubberduck.Properties;
1+
using System;
2+
using System.Xml.Serialization;
33
using Rubberduck.UI;
44
using Rubberduck.UI.CodeExplorer;
55
using Rubberduck.UI.Inspections;
@@ -21,7 +21,7 @@ public interface IWindowSettings
2121
}
2222

2323
[XmlType(AnonymousType = true)]
24-
public class WindowSettings : IWindowSettings
24+
public class WindowSettings : IWindowSettings, IEquatable<WindowSettings>
2525
{
2626
public WindowSettings()
2727
: this(false, false, false, false, false)
@@ -71,5 +71,15 @@ public bool IsWindowVisible(DockableToolwindowPresenter candidate)
7171
//Oh. Hello. I have no clue who you are...
7272
return false;
7373
}
74+
75+
public bool Equals(WindowSettings other)
76+
{
77+
return other != null &&
78+
CodeExplorerVisibleOnStartup == other.CodeExplorerVisibleOnStartup &&
79+
CodeInspectionsVisibleOnStartup == other.CodeInspectionsVisibleOnStartup &&
80+
SourceControlVisibleOnStartup == other.SourceControlVisibleOnStartup &&
81+
TestExplorerVisibleOnStartup == other.TestExplorerVisibleOnStartup &&
82+
TodoExplorerVisibleOnStartup == other.TodoExplorerVisibleOnStartup;
83+
}
7484
}
7585
}

Rubberduck.SettingsProvider/XmlPersistanceService.cs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,26 @@
88

99
namespace Rubberduck.SettingsProvider
1010
{
11-
public class XmlPersistanceService<T> : IFilePersistanceService<T> where T : new()
11+
public class XmlPersistanceService<T> : IFilePersistanceService<T> where T : class, IEquatable<T>, new()
1212
{
1313
private readonly string _rootPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Rubberduck");
1414
private readonly UTF8Encoding _outputEncoding = new UTF8Encoding(false);
1515
private const string DefaultConfigFile = "rubberduck.config";
1616
private const string RootElement = "Configuration";
1717

18+
// ReSharper disable once StaticFieldInGenericType
1819
private static readonly XmlSerializerNamespaces EmptyNamespace =
1920
new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });
2021

22+
// ReSharper disable once StaticFieldInGenericType
2123
private static readonly XmlWriterSettings OutputXmlSettings = new XmlWriterSettings
2224
{
2325
Encoding = new UTF8Encoding(false),
2426
Indent = true,
2527
};
2628

29+
private T _cached;
30+
2731
private string _filePath;
2832
public string FilePath
2933
{
@@ -33,6 +37,11 @@ public string FilePath
3337

3438
public T Load(T toDeserialize)
3539
{
40+
if (_cached != null)
41+
{
42+
return _cached;
43+
}
44+
3645
var type = typeof(T);
3746

3847
if (!File.Exists(FilePath))
@@ -52,8 +61,8 @@ public T Load(T toDeserialize)
5261
var deserializer = new XmlSerializer(type);
5362
try
5463
{
55-
var output = deserializer.Deserialize(reader);
56-
return (T)Convert.ChangeType(output, type);
64+
_cached = (T)Convert.ChangeType(deserializer.Deserialize(reader), type);
65+
return _cached;
5766
}
5867
catch
5968
{
@@ -62,11 +71,10 @@ public T Load(T toDeserialize)
6271
}
6372
}
6473

65-
private static T FailedLoadReturnValue()
66-
{
67-
return (T)Convert.ChangeType(null, typeof(T));
68-
}
69-
74+
private static T FailedLoadReturnValue()
75+
{
76+
return (T)Convert.ChangeType(null, typeof(T));
77+
}
7078

7179
public void Save(T toSerialize)
7280
{
@@ -100,6 +108,7 @@ public void Save(T toSerialize)
100108
using (var xml = XmlWriter.Create(FilePath, OutputXmlSettings))
101109
{
102110
doc.WriteTo(xml);
111+
_cached = toSerialize;
103112
}
104113
}
105114

0 commit comments

Comments
 (0)