Skip to content

Commit 89ec001

Browse files
committed
added ninject interceptors
1 parent cfbf0d0 commit 89ec001

File tree

10 files changed

+240
-104
lines changed

10 files changed

+240
-104
lines changed

RetailCoder.VBE/Extension.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using System.Reflection;
1111
using System.Runtime.InteropServices;
1212
using System.Windows.Forms;
13+
using Ninject.Extensions.Interception;
1314

1415
namespace Rubberduck
1516
{
@@ -37,13 +38,13 @@ public void OnBeginShutdown(ref Array custom)
3738
// ReSharper disable InconsistentNaming
3839
public void OnConnection(object Application, ext_ConnectMode ConnectMode, object AddInInst, ref Array custom)
3940
{
40-
_kernel = new StandardKernel(new FuncModule());
41+
_kernel = new StandardKernel(new NinjectSettings{LoadExtensions = true}, new FuncModule(), new DynamicProxyModule());
4142

4243
try
4344
{
4445
var currentDomain = AppDomain.CurrentDomain;
4546
currentDomain.AssemblyResolve += LoadFromSameFolder;
46-
_kernel.Load(new RubberduckModule(_kernel, (VBE)Application, (AddIn)AddInInst));
47+
_kernel.Load(new RubberduckModule((VBE)Application, (AddIn)AddInInst));
4748
_app = _kernel.Get<App>();
4849
_app.Startup();
4950
}

RetailCoder.VBE/Inspections/IInspection.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using Rubberduck.Root;
34

45
namespace Rubberduck.Inspections
56
{
@@ -9,9 +10,11 @@ namespace Rubberduck.Inspections
910
public interface IInspection : IInspectionModel, IComparable<IInspection>, IComparable
1011
{
1112
/// <summary>
12-
/// Runs code inspection on specified parse trees.
13+
/// Runs code inspection and returns inspection results.
1314
/// </summary>
1415
/// <returns>Returns inspection results, if any.</returns>
16+
[TimedCallIntercept]
17+
[EnumerableCounterIntercept]
1518
IEnumerable<InspectionResultBase> GetInspectionResults();
1619

1720
/// <summary>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using Ninject.Extensions.Interception;
5+
using Ninject.Infrastructure.Language;
6+
using NLog;
7+
8+
namespace Rubberduck.Root
9+
{
10+
/// <summary>
11+
/// An attribute that makes an intercepted method call log the number of items returned.
12+
/// </summary>
13+
public class EnumerableCounterInterceptAttribute : Attribute { }
14+
15+
/// <summary>
16+
/// An interceptor that logs the number of items returned by an intercepted invocation that returns any IEnumerable{T}.
17+
/// </summary>
18+
public class EnumerableCounterInterceptor<T> : InterceptorBase
19+
{
20+
private readonly ILogger _logger = LogManager.GetCurrentClassLogger();
21+
22+
protected override void AfterInvoke(IInvocation invocation)
23+
{
24+
if (!invocation.Request.Method.HasAttribute<EnumerableCounterInterceptAttribute>()) { return; }
25+
26+
var result = invocation.ReturnValue as IEnumerable<T>;
27+
if (result != null)
28+
{
29+
_logger.Trace("Intercepted invocation of '{0}.{1}' returned {2} objects.",
30+
invocation.Request.Target.GetType().Name, invocation.Request.Method.Name, result.Count());
31+
}
32+
}
33+
}
34+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System;
2+
3+
namespace Rubberduck.Root
4+
{
5+
public class InterceptedException : Exception
6+
{
7+
public InterceptedException(Exception inner)
8+
: this(inner.Message, inner) { }
9+
10+
public InterceptedException(string message, Exception inner)
11+
: base(message, inner) { }
12+
}
13+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System;
2+
using Ninject.Extensions.Interception;
3+
4+
namespace Rubberduck.Root
5+
{
6+
public abstract class InterceptorBase : IInterceptor
7+
{
8+
public void Intercept(IInvocation invocation)
9+
{
10+
try
11+
{
12+
BeforeInvoke(invocation);
13+
invocation.Proceed();
14+
}
15+
catch (Exception exception)
16+
{
17+
OnError(invocation, exception);
18+
}
19+
finally
20+
{
21+
AfterInvoke(invocation);
22+
}
23+
}
24+
25+
protected virtual void BeforeInvoke(IInvocation invocation) { }
26+
27+
protected virtual void AfterInvoke(IInvocation invocation) { }
28+
29+
protected virtual void OnError(IInvocation invocation, Exception exception)
30+
{
31+
throw new InterceptedException(exception);
32+
}
33+
}
34+
}

RetailCoder.VBE/Root/RubberduckModule.cs

Lines changed: 96 additions & 96 deletions
Large diffs are not rendered by default.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using System;
2+
using System.Diagnostics;
3+
using Ninject.Extensions.Interception;
4+
using Ninject.Infrastructure.Language;
5+
using NLog;
6+
7+
namespace Rubberduck.Root
8+
{
9+
/// <summary>
10+
/// An attribute that makes an intercepted method call log the duration of its execution.
11+
/// </summary>
12+
public class TimedCallInterceptAttribute : Attribute { }
13+
14+
/// <summary>
15+
/// An interceptor that logs the duration of an intercepted invocation.
16+
/// </summary>
17+
public class TimedCallLoggerInterceptor : InterceptorBase
18+
{
19+
private readonly ILogger _logger = LogManager.GetCurrentClassLogger();
20+
private readonly Stopwatch _stopwatch = new Stopwatch();
21+
private bool _running;
22+
23+
protected override void BeforeInvoke(IInvocation invocation)
24+
{
25+
_running = invocation.Request.Method.HasAttribute<TimedCallInterceptAttribute>();
26+
if(!_running) { return; }
27+
28+
_stopwatch.Reset();
29+
_stopwatch.Start();
30+
}
31+
32+
protected override void AfterInvoke(IInvocation invocation)
33+
{
34+
if (!_running) { return; }
35+
36+
_stopwatch.Stop();
37+
_logger.Trace("Intercepted invocation of '{0}.{1}' ran for {2}ms",
38+
invocation.Request.Target.GetType().Name, invocation.Request.Method.Name, _stopwatch.ElapsedMilliseconds);
39+
}
40+
}
41+
}

RetailCoder.VBE/Rubberduck.csproj

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,13 @@
245245
<Reference Include="Ninject.Extensions.Factory">
246246
<HintPath>..\packages\Ninject.Extensions.Factory.3.2.1.0\lib\net45-full\Ninject.Extensions.Factory.dll</HintPath>
247247
</Reference>
248-
<Reference Include="Ninject.Extensions.NamedScope">
249-
<HintPath>..\packages\Ninject.Extensions.NamedScope.3.2.0.0\lib\net45-full\Ninject.Extensions.NamedScope.dll</HintPath>
248+
<Reference Include="Ninject.Extensions.Interception, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
249+
<HintPath>..\packages\Ninject.Extensions.Interception.3.2.0.0\lib\net45-full\Ninject.Extensions.Interception.dll</HintPath>
250+
<Private>True</Private>
251+
</Reference>
252+
<Reference Include="Ninject.Extensions.Interception.DynamicProxy, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
253+
<HintPath>..\packages\Ninject.Extensions.Interception.DynamicProxy.3.2.0.0\lib\net45-full\Ninject.Extensions.Interception.DynamicProxy.dll</HintPath>
254+
<Private>True</Private>
250255
</Reference>
251256
<Reference Include="PresentationCore" />
252257
<Reference Include="PresentationFramework" />
@@ -386,6 +391,10 @@
386391
<Compile Include="Refactorings\ExtractMethod\IExtractMethodProc.cs" />
387392
<Compile Include="Refactorings\ExtractMethod\IExtractMethodRule.cs" />
388393
<Compile Include="Refactorings\ExtractMethod\IExtractMethodSelectionValidation.cs" />
394+
<Compile Include="Root\EnumerableCounterInterceptor.cs" />
395+
<Compile Include="Root\InterceptedException.cs" />
396+
<Compile Include="Root\InterceptorBase.cs" />
397+
<Compile Include="Root\TimedCallLoggerInterceptor.cs" />
389398
<Compile Include="Settings\CodeInspectionConfigProvider.cs" />
390399
<Compile Include="Settings\GeneralConfigProvider.cs" />
391400
<Compile Include="Settings\HotkeySettings.cs" />

RetailCoder.VBE/UI/Command/MenuItems/ParentMenus/ParentMenuItemBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,9 @@ public void EvaluateCanExecute(RubberduckParserState state)
109109
}
110110

111111
var commandItem = kvp.Key as ICommandMenuItem;
112-
if (commandItem != null)
112+
if (commandItem != null && kvp.Value != null)
113113
{
114-
kvp.Value.Enabled = commandItem.EvaluateCanExecute(state);
114+
kvp.Value.Enabled = commandItem.EvaluateCanExecute(state);
115115
}
116116
}
117117
}

RetailCoder.VBE/packages.config

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
<package id="Ninject" version="3.2.2.0" targetFramework="net45" />
77
<package id="Ninject.Extensions.Conventions" version="3.2.0.0" targetFramework="net45" />
88
<package id="Ninject.Extensions.Factory" version="3.2.1.0" targetFramework="net45" />
9-
<package id="Ninject.Extensions.NamedScope" version="3.2.0.0" targetFramework="net45" />
9+
<package id="Ninject.Extensions.Interception" version="3.2.0.0" targetFramework="net45" />
10+
<package id="Ninject.Extensions.Interception.DynamicProxy" version="3.2.0.0" targetFramework="net45" />
1011
<package id="NLog" version="4.0.1" targetFramework="net45" />
1112
<package id="NLog.Schema" version="4.0.1" targetFramework="net45" />
1213
</packages>

0 commit comments

Comments
 (0)