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(() => 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 default_database = new Func(() => new database()); public static Func default_logger = new Func(() => new logger()); public static Func db { get; set; } public static Func logger { get; set; } } public class database { } public class logger { public bool verbose { get; set; } public void log(bool isverbose, Func 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 obj); public delegate void MethodDelegate(TIn obj); public delegate void MethodDelegate(); public static string method_info(MethodInfo methodInfo) { return methodInfo.DeclaringType.FullName + "." + methodInfo.Name; } public static TOut IntoExpr(this TIn obj, MethodDelegate 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(this TIn obj, MethodDelegate del) { del(obj); contextfuncs.logger().log(true, () => String.Format("{0}({1}): void", method_info(del.Method), obj.ToString())); } public static void IntoExpr(this TIn obj, MethodDelegate del) { del(); contextfuncs.logger().log(true, () => String.Format("{0}(): void", method_info(del.Method))); } public static TOut Into(this TIn obj, Func f) { return f(obj); } public static T Passthrough(this T obj) { return obj; } public static T PassthroughAssert(this T obj, bool condition) { if (condition) return obj; throw new Exception("Condition not met"); } public static void Into(this TIn obj, Action f) { f(obj); } }