Skip to content

Instantly share code, notes, and snippets.

@jbrestan
Last active August 29, 2015 14:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbrestan/359a855df26fe9bf2da6 to your computer and use it in GitHub Desktop.
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.
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[]\"!");
}
}
}
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