Last active
April 12, 2017 21:51
-
-
Save zvirja/56543e5c35cf910e4d1eec87d0fd02f3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class DiagnosticsSubstitutionContext : ISubstitutionContext | |
{ | |
[ThreadStatic] | |
private static IList<IArgumentSpecification> LastDequeuedList; | |
private static ConcurrentDictionary<IArgumentSpecification, ArgumentInfo> ArgumentInfos { get; } = new ConcurrentDictionary<IArgumentSpecification, ArgumentInfo>(); | |
private class ArgumentInfo | |
{ | |
public string CreationStack { get; } | |
public int DequeueCounter { get; set; } | |
public int ThreadId { get; } | |
public DateTime CreationTime { get; } | |
public ArgumentInfo() | |
{ | |
CreationStack = Environment.StackTrace; | |
ThreadId = Thread.CurrentThread.ManagedThreadId; | |
CreationTime = DateTime.UtcNow; | |
} | |
} | |
static DiagnosticsSubstitutionContext() | |
{ | |
//Init hook | |
var context = new DiagnosticsSubstitutionContext(SubstitutionContext.Current); | |
SubstitutionContext.Current = context; | |
AppDomain.CurrentDomain.FirstChanceException += | |
(sender, args) => | |
{ | |
if (args.Exception is AmbiguousArgumentsException) | |
{ | |
var lastList = LastDequeuedList; | |
var enqueueInfo = lastList.Select(x => new { Spec = x, Info = ArgumentInfos[x] }).ToArray(); | |
//TODO: PUT breakpoint here or log enqueueInfo. | |
Thread.CurrentThread.ManagedThreadId | |
enqueueInfo[x].Spec | |
enqueueInfo[x].Info.CreationStack | |
enqueueInfo[x].Info.CreationTime.ToString("o") | |
enqueueInfo[x].Info.ThreadId | |
enqueueInfo[x].Info.DequeueCounter | |
} | |
}; | |
} | |
public static void Init() { } | |
private readonly ISubstitutionContext _original; | |
private DiagnosticsSubstitutionContext(ISubstitutionContext current) | |
{ | |
_original = current; | |
} | |
public void EnqueueArgumentSpecification(IArgumentSpecification spec) | |
{ | |
ArgumentInfos.TryAdd(spec, new ArgumentInfo()); | |
_original.EnqueueArgumentSpecification(spec); | |
} | |
public IList<IArgumentSpecification> DequeueAllArgumentSpecifications() | |
{ | |
var result = _original.DequeueAllArgumentSpecifications(); | |
LastDequeuedList = result; | |
foreach (var argumentSpecification in result) | |
{ | |
ArgumentInfos[argumentSpecification].DequeueCounter++; | |
} | |
return result; | |
} | |
//DELEGATING IMPLEMENTATION - NO CHANGES | |
public ISubstituteFactory SubstituteFactory => _original.SubstituteFactory; | |
public SequenceNumberGenerator SequenceNumberGenerator => _original.SequenceNumberGenerator; | |
public ConfiguredCall LastCallShouldReturn(IReturn value, MatchArgs matchArgs) => _original.LastCallShouldReturn(value, matchArgs); | |
public void LastCallRouter(ICallRouter callRouter) => _original.LastCallRouter(callRouter); | |
public ICallRouter GetCallRouterFor(object substitute) => _original.GetCallRouterFor(substitute); | |
public void RaiseEventForNextCall(Func<ICall, object[]> getArguments) => _original.RaiseEventForNextCall(getArguments); | |
public IQueryResults RunQuery(Action calls) => _original.RunQuery(calls); | |
public bool IsQuerying => _original.IsQuerying; | |
public void AddToQuery(object target, ICallSpecification callSpecification) => _original.AddToQuery(target, callSpecification); | |
public void ClearLastCallRouter() => _original.ClearLastCallRouter(); | |
public IRouteFactory GetRouteFactory() => _original.GetRouteFactory(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment