Skip to content

Instantly share code, notes, and snippets.

@joeriks
Last active August 29, 2015 14:11
Show Gist options
  • Save joeriks/431f3bb234ffc79d5100 to your computer and use it in GitHub Desktop.
Save joeriks/431f3bb234ffc79d5100 to your computer and use it in GitHub Desktop.
fun with delegates, expressive namings, pipe forwards, func di and auto-method-name-logging in C#
using System;
using System.Reflection;
public class Program
{
static void Main(string[] args)
{
// setup db and logger using funcs
// use default
contextfuncs.db = contextfuncs.default_database;
// set verbose to true to demonstrate
// explicit logging with method names and results
contextfuncs.logger = new Func<logger>(() => new logger { verbose = true });
// pipe the commands
// use expressive naming
// but avoid keeping each result in a separate var
"Give me a product id please"
.IntoExpr(command_line_operations.ask_user_for_integer)
.IntoExpr(query_the_database.products.with_id)
.IntoExpr(format_strings.product_formatted_for_commandline)
.IntoExpr(command_line_operations.write_message_to_user_and_wait_for_enter);
}
}
public static class contextfuncs
{
public static Func<database> default_database = new Func<database>(() => new database());
public static Func<logger> default_logger = new Func<logger>(() => new logger());
public static Func<database> db { get; set; }
public static Func<logger> logger { get; set; }
}
public class database { }
public class logger
{
public bool verbose { get; set; }
public void log(bool isverbose, Func<string> logmessageFunc)
{
if (isverbose == verbose || !isverbose)
{
var logmessage = logmessageFunc();
var color = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.DarkCyan;
Console.WriteLine(DateTime.Now.ToLongTimeString() + "> " + logmessage);
Console.ForegroundColor = color;
}
}
}
public class context
{
public database database { get; set; }
public logger logger { get; set; }
}
public static class command_line_operations
{
public static int ask_user_for_integer(string ask_user)
{
Console.WriteLine(ask_user);
var input = Console.ReadLine();
return Int32.Parse(input);
}
public static void wait_for_enter()
{
Console.ReadLine();
}
public static string write_message_to_user_and_wait_for_enter(format_strings.string_formatted_for_commandline message)
{
Console.WriteLine(message);
return Console.ReadLine();
}
}
public static class format_strings
{
public class string_formatted_for_commandline
{
public string message { get; set; }
public override string ToString()
{
return message.ToString();
}
public string_formatted_for_commandline(string message)
{
this.message = message;
}
}
public static string_formatted_for_commandline product_formatted_for_commandline(Product p)
{
return new string_formatted_for_commandline(String.Format("Product name: '{0}' Id: {1}", p.Name, p.Id));
}
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
}
public static class query_the_database
{
public static void assert_the_database_is_available()
{
if (contextfuncs.db == null || contextfuncs.db() == null) throw new Exception("Db error");
}
public static class products
{
public static Product with_id(int id)
{
assert_the_database_is_available();
return new Product { Id = id, Name = "Some name" };
}
}
}
public static class IntoExtensions
{
public delegate TOut MethodDelegate<TIn, TOut>(TIn obj);
public delegate void MethodDelegate<TIn>(TIn obj);
public delegate void MethodDelegate();
public static string method_info(MethodInfo methodInfo)
{
return methodInfo.DeclaringType.FullName + "." + methodInfo.Name;
}
public static TOut IntoExpr<TIn, TOut>(this TIn obj, MethodDelegate<TIn, TOut> del)
{
var result = del(obj);
contextfuncs.logger().log(true, () => String.Format("{0}({1}): {2}", method_info(del.Method), obj.ToString(), result.ToString()));
return result;
}
public static void IntoExpr<TIn>(this TIn obj, MethodDelegate<TIn> del)
{
del(obj);
contextfuncs.logger().log(true, () => String.Format("{0}({1}): void", method_info(del.Method), obj.ToString()));
}
public static void IntoExpr<TIn>(this TIn obj, MethodDelegate del)
{
del();
contextfuncs.logger().log(true, () => String.Format("{0}(): void", method_info(del.Method)));
}
public static TOut Into<TIn, TOut>(this TIn obj, Func<TIn, TOut> f)
{ return f(obj); }
public static T Passthrough<T>(this T obj)
{
return obj;
}
public static T PassthroughAssert<T>(this T obj, bool condition)
{
if (condition) return obj;
throw new Exception("Condition not met");
}
public static void Into<TIn>(this TIn obj, Action<TIn> f)
{ f(obj); }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment