forked from rubberduck-vba/Rubberduck
-
Notifications
You must be signed in to change notification settings - Fork 12
/
RubberduckModule.cs
117 lines (100 loc) · 4.4 KB
/
RubberduckModule.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using Microsoft.Vbe.Interop;
using Ninject;
using Ninject.Extensions.Conventions;
using Ninject.Extensions.NamedScope;
using Ninject.Modules;
using Rubberduck.Inspections;
using Rubberduck.Parsing;
using Rubberduck.Settings;
using Rubberduck.UI;
using Rubberduck.UI.CodeInspections;
using Rubberduck.UI.Command;
using Rubberduck.UI.UnitTesting;
using Rubberduck.VBEditor.Extensions;
using Rubberduck.VBEditor.VBEHost;
namespace Rubberduck.Root
{
public class RubberduckModule : NinjectModule
{
private readonly IKernel _kernel;
private readonly VBE _vbe;
private readonly AddIn _addin;
public RubberduckModule(IKernel kernel, VBE vbe, AddIn addin)
{
_kernel = kernel;
_vbe = vbe;
_addin = addin;
}
public override void Load()
{
Debug.Print("in RubberduckModule.Load()");
_kernel.Bind<App>().ToSelf().InSingletonScope();
// bind VBE and AddIn dependencies to host-provided instances.
_kernel.Bind<VBE>().ToConstant(_vbe);
_kernel.Bind<AddIn>().ToConstant(_addin);
BindCodeInspectionTypes();
var assemblies = new[]
{
Assembly.GetExecutingAssembly(),
Assembly.GetAssembly(typeof(IHostApplication)),
Assembly.GetAssembly(typeof(IRubberduckParser))
};
ApplyConfigurationConvention(assemblies);
ApplyDefaultInterfacesConvention(assemblies);
ApplyAbstractFactoryConvention(assemblies);
Bind<TestExplorerModelBase>().To<StandardModuleTestExplorerModel>().InSingletonScope();
Bind<IPresenter>().To<TestExplorerDockablePresenter>()
.WhenInjectedInto<TestExplorerCommand>()
.InSingletonScope()
.WithConstructorArgument<IDockableUserControl>(new TestExplorerWindow { ViewModel = _kernel.Get<TestExplorerViewModel>() });
Bind<IPresenter>().To<CodeInspectionsDockablePresenter>()
.WhenInjectedInto<RunCodeInspectionsCommand>()
.InSingletonScope()
.WithConstructorArgument<IDockableUserControl>(new CodeInspectionsWindow { ViewModel = _kernel.Get<InspectionResultsViewModel>() });
Debug.Print("completed RubberduckModule.Load()");
}
private void ApplyDefaultInterfacesConvention(IEnumerable<Assembly> assemblies)
{
_kernel.Bind(t => t.From(assemblies)
.SelectAllClasses()
// inspections & factories have their own binding rules
.Where(type => !type.Name.EndsWith("Factory") && !type.GetInterfaces().Contains(typeof(IInspection)))
.BindDefaultInterface()
.Configure(binding => binding.InCallScope())); // TransientScope wouldn't dispose disposables
}
// note: settings namespace classes are injected in singleton scope
private void ApplyConfigurationConvention(IEnumerable<Assembly> assemblies)
{
_kernel.Bind(t => t.From(assemblies)
.SelectAllClasses()
.InNamespaceOf<Configuration>()
.BindAllInterfaces()
.Configure(binding => binding.InSingletonScope()));
}
// note convention: abstract factory interface names end with "Factory".
private void ApplyAbstractFactoryConvention(IEnumerable<Assembly> assemblies)
{
_kernel.Bind(t => t.From(assemblies)
.SelectAllInterfaces()
.Where(type => type.Name.EndsWith("Factory"))
.BindToFactory()
.Configure(binding => binding.InSingletonScope()));
}
// note: IInspection implementations are discovered in the Rubberduck assembly via reflection.
private void BindCodeInspectionTypes()
{
var inspections = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(type => type.GetInterfaces().Contains(typeof (IInspection)));
// multibinding for IEnumerable<IInspection> dependency
foreach (var inspection in inspections)
{
_kernel.Bind<IInspection>().To(inspection).InSingletonScope();
}
}
}
}