Last active
August 29, 2015 14:26
-
-
Save jbrestan/359a855df26fe9bf2da6 to your computer and use it in GitHub Desktop.
Dynamic logger experiment. Allows writing descriptive log calls without the need to implement them by hand.
This file contains 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 AutoLogger : DynamicObject | |
{ | |
private readonly Action<string> _logMethod; | |
const string SplitterName = "splitNameBy"; | |
public AutoLogger(Action<string> logMethod) | |
{ | |
_logMethod = logMethod; | |
} | |
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) | |
{ | |
result = null; | |
var argCount = binder.CallInfo.ArgumentCount; | |
var namedCount = binder.CallInfo.ArgumentNames.Count; | |
var paddedNames = Enumerable | |
.Repeat<string>("param", argCount - namedCount) | |
.Select((n, i) => string.Intern(n + i)) | |
.Concat(binder.CallInfo.ArgumentNames); | |
var argsWithNames = args | |
.Zip(paddedNames, (arg, name) => new {Value = arg, Name = name}) | |
.ToArray(); | |
var splitter = argsWithNames.FirstOrDefault(x => x.Name == SplitterName); | |
var messageText = new StringBuilder(splitter != null | |
? SplitJoinDefault(splitter.Value, binder.Name) | |
: SplitJoinCamelCase(binder.Name)); | |
foreach (var arg in argsWithNames) | |
{ | |
if (arg.Name == SplitterName) { continue; } | |
messageText.AppendLine().AppendFormat("{0}: {1}", arg.Name, arg.Value.ToString()); | |
} | |
_logMethod(messageText.ToString()); | |
return true; | |
} | |
private string SplitJoinCamelCase(string source) | |
{ | |
return Regex.Replace(source, @"\B[A-Z]", m => " " + m.ToString().ToLower()); | |
} | |
private string SplitJoinDefault(object splitter, string source) | |
{ | |
if (splitter is char[]) | |
{ | |
return string.Join(" ", source.Split((char[])splitter)); | |
} | |
else | |
{ | |
throw new InvalidOperationException(SplitterName + " must be of type \"char[]\"!"); | |
} | |
} | |
} |
This file contains 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
dynamic log = new AutoLogger(str => str.Dump()); | |
try | |
{ | |
log.BeforeTheBoom(); | |
throw new Exception("Boom!"); | |
} | |
catch (Exception ex) | |
{ | |
log.FooABCHappensEveryTime(5, ex, boo: 1); | |
} | |
/* Outputs: | |
Before the boom | |
Foo a b c happens every time | |
param0: 5 | |
param1: System.Exception: Boom! | |
at UserQuery.Main() in c:\Users\jb185293\AppData\Local\Temp\LINQPad\_zaorlgtw\query_crclxx.cs:line 36 | |
boo: 1 | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment