Thursday, December 13, 2012

Export strongly-typed model to Excel. Making a DRY-adhering API

Let's say we have an API than can export data to Excel file via ASP.NET MVC: (Download the Excel exporting component from: http://epplus.codeplex.com/)

public class ExcelResult : ActionResult
{
 
    public ExcelPackage ExcelPackage { get; set; }
    public string FileName { get; set; }
 
 
    public override void ExecuteResult(ControllerContext context)
    {
        context.HttpContext.Response.AppendHeader("Content-type", "application/vnd.ms-excel");
        context.HttpContext.Response.AppendHeader("Content-disposition", string.Format("attachment; filename={0}.xls", FileName));
 
 
        byte[] a = ExcelPackage.GetAsByteArray();
        context.HttpContext.Response.OutputStream.Write(a, 0, a.Length);
    }
}



And then we want to re-use that component able to export list of employee, we can do this:


public class EmployeeExcelResult : ExcelResult
{
    IList<Employee> _employees;
 
 
    public EmployeeExcelResult(IList<Employee> employees)
    {
        _employees = employees;
    }
 
 
    public override void ExecuteResult(ControllerContext context)
    {
        ExcelPackage = new ExcelPackage();
 
        ExcelWorksheet sheet = ExcelPackage.Workbook.Worksheets.Add("Export");
 
 
        sheet.Cells[1, 1].Value = "Firstname";
        sheet.Cells[2, 1].LoadFromCollection(_employees.Select(y => new {Value = y.FirstName}));
 
        sheet.Cells[1, 2].Value = "Lastname";
        sheet.Cells[2, 2].LoadFromCollection(_employees.Select(y => new { Value = y.LastName }));
 
        sheet.Cells[1, 2].Value = "Age";
        sheet.Cells[2, 2].LoadFromCollection(_employees.Select(y => new { Value = y.Age}));
 
 
        base.ExecuteResult(context);
    }
 
}


And we will use that like this in the controller's action:


public ActionResult ExportEmployeesToExcel()
{
 
 IList<Employee> employees = new List<Employee>()
 {
   new Employee() { FirstName = "John", MiddleName = "Winston", LastName = "Lennon", Age = 12345, SongsPercent = 0.301234},
   new Employee() { FirstName = "Paul", MiddleName = "Phoenix", LastName = "McCartney", Age = 67891234, SongsPercent = 0.205678},
   new Employee() { FirstName = "George", MiddleName = "Tough", LastName = "Harisson", Age = 3456 },
   new Employee() { FirstName = "Ringo", MiddleName = "Drum", LastName = "Starr", Age = 3456 }
 };    
 
 return new EmployeeExcelResult(employees);
}



It should be noted that no ethically-trained software engineer would ever consent to write a DestroyBaghdad procedure. Basic professional ethics would instead require him to write a DestroyCity procedure, to which Baghdad could be given as a parameter -- Nathaniel Borenstein



The approach above(class EmployeeExcelResult), though it adheres to two of the basic OOP tenets(i.e. inheritance and polymorphism), has a problem if we need to use another kind of list to be exported, say list of product. Aside from that approach is not reusable, it's error prone too. If you are a keen observer, you'll notice that the Age property overwrites the Lastname property, resulting to two exported columns only.


We got to make the component very re-usable:


public class ExcelResult<T> : ExcelResult
{
    IEnumerable<T> _list;
 
 
    public ExcelResult(IEnumerable<T> list)
    {
        _list = list;
    }
 
 
    public override void ExecuteResult(ControllerContext context)
    {
        ExcelPackage = new ExcelPackage();
 
        ExcelWorksheet sheet = ExcelPackage.Workbook.Worksheets.Add("Export");
 
        int ordinal = 0;
        foreach (System.Reflection.PropertyInfo pi in typeof(T).GetProperties())
        {
            ++ordinal;
 
            sheet.Cells[1, ordinal].Value = pi.Name;
            sheet.Cells[2, ordinal].LoadFromCollection(_list.Select(x => new {Value = GetPropValue(x, pi.Name)}));
        }
        base.ExecuteResult(context);
    }
 
    // In this age of stackoverflow, who needs MSDN?
    // http://stackoverflow.com/questions/1196991/get-property-value-from-string-using-reflection-in-c-sharp
    static object GetPropValue(object src, string propName)
    {
        return src.GetType().GetProperty(propName).GetValue(src, null);
    }
 
}
 
.
.
.
 
public ActionResult ExportEmployeeList()
{
 IList<Employee> employees = new List<Employee>()
 {
   new Employee() { FirstName = "John", MiddleName = "Winston", LastName = "Lennon", Age = 12345, SongsPercent = 0.301234},
   new Employee() { FirstName = "Paul", MiddleName = "Phoenix", LastName = "McCartney", Age = 67891234, SongsPercent = 0.205678},
   new Employee() { FirstName = "George", MiddleName = "Tough", LastName = "Harisson", Age = 3456 },
   new Employee() { FirstName = "Ringo", MiddleName = "Drum", LastName = "Starr", Age = 3456 }
 };
 return new ExcelResult<Employee>(employees);
}


That's flexible now, but we can improve it more. We can make it more flexible by letting us able to specify which columns should be exported to Excel only, and able to specify the column's format. There are three approach we can use when designing an API such as that.

  • First we maintain a dictionary of column's metadata, where the metadata indicates the column's label and formatting. But dictionary is a non-starter as it promotes stringly-typed programming.
  • Second is we can use attributes, but that would entail decorating the attributes directly to the concerned class, what if the other party(think B2B's provider) won't allow you to add attributes to their classes? The work-around on this second option is to use buddy classes, this would work only if the consuming party's classes are generated with partials(e.g. WCF) on them. But even buddy classes is an option, buddy classes violates DRY principle, and refactoring wouldn't be available also. Attributes-based API won't let us be creative, even a simple API such as passing the method's address to the function is not possible with attribute, hence necessitates passing the method as string, and calling the method through reflection. Stringly-typed API is brittle and non-discoverable.

  • That leaves us with the third option, let's design an API that avoids violating DRY principle, and avoids stringly-typed programming to boot. We can use Fluent API and C#'s Expression


We can make a better design for an API if we design it from the end, that is we design it how we wanted to use it. So here's how we wanted to use our API, this is similar to Fluent NHibernate: https://github.com/jagregory/fluent-nhibernate/wiki/Getting-started



public ActionResult ExportEmployeesToExcel()
{    
    IList<Employee> employees = new List<Employee>()
            {
                new Employee() { FirstName = "John", MiddleName = "Winston", LastName = "Lennon", Age = 12345, SongsPercent = 0.301234},
                new Employee() { FirstName = "Paul", MiddleName = "Phoenix", LastName = "McCartney", Age = 67891234, SongsPercent = 0.205678},
                new Employee() { FirstName = "George", MiddleName = "Tough", LastName = "Harisson", Age = 3456 },
                new Employee() { FirstName = "Ringo", MiddleName = "Drum", LastName = "Starr", Age = 3456 }
            };
 
    return new ExcelResultFromList<Employee>(employees)
    {                           
       Filename = "Employees",
       ExcelMapping = new EmployeeExcelMapping()
    };
}
 
.
.
.
 
public class EmployeeExcelMapping : ExcelMapping<Employee>
{
    public EmployeeExcelMapping()
    {
        Include(x => x.LastName).Label("Family Name");
        Include(x => x.FirstName);            
        Include(x => x.Age).NumberFormat("#,#00.00");
        Include(x => x.SongsPercent).Label("Song%").NumberFormat("0.000%");
        
        // we didn't include the middle name to exported excel 
    }
}




The above will appeal to you if you are a Fluent NHibernate fan. If you have used NHibernate 3.2, you might already learned there's another style of mapping by code which is built-in in NHibernate, you can inline-ly(if there's such a word) map your class with the latest NHibernate. Meaning, you don't have to create a separate class for your mapping, this is what "loquacious" (such an unfortunate name, the fluent nomenclature was already taken by others) mapping facilitates. The NHibernate's loquacious API has a more one-stop-shop feel into it. The API below is similar to this style: http://fabiomaulo.blogspot.com/2011/04/nhibernate-32-mapping-by-code.html



public ActionResult ExportEmployeesToExcel()
{
 
 IList<Employee> employees = new List<Employee>()
 {
   new Employee() { FirstName = "John", MiddleName = "Winston", LastName = "Lennon", Age = 12345, SongsPercent = 0.301234},
   new Employee() { FirstName = "Paul", MiddleName = "Phoenix", LastName = "McCartney", Age = 67891234, SongsPercent = 0.205678},
   new Employee() { FirstName = "George", MiddleName = "Tough", LastName = "Harisson", Age = 3456 },
   new Employee() { FirstName = "Ringo", MiddleName = "Drum", LastName = "Starr", Age = 3456 }
 };
 
 return ExcelResultFromList.Create<Employee>
                (list: employees, 
                filename: "Employees",
                mapAction: e =>
                                {
                                    e.Include(x => x.LastName).Label("Apelyido");
                                    e.Include(x => x.FirstName);
                                    e.Include(x => x.Age).NumberFormat("#,#00.00");
                                    e.Include(x => x.SongsPercent).Label("Song%").NumberFormat("0.000%");
                                });
} 


You can choose either fluent style or the loquacious style. Whichever mental model suits you



That's it, that's how we want our API to be, a good .NET citizen, very respecting of POCO. Very respecting of DRY principle: http://en.wikipedia.org/wiki/Don't_repeat_yourself




Expand the full code below to see how to implement the API above:

using System.Linq;


public class ExcelMapping<T>
{
    readonly System.Collections.Generic.IList<ExportMetaData<T>> _exportList = new System.Collections.Generic.List<ExportMetaData<T>>();
    public System.Collections.Generic.IList<ExportMetaData<T>> ExportList { get { return _exportList; } }



    public ExportPart<T> Include<TProp>(System.Linq.Expressions.Expression<System.Func<T, TProp>> p)
    {
        string name = new ExpressionGetter.PropertyPathVisitor().GetPropertyPath(p);

        var emd = new ExportMetaData<T>();
        ExportList.Add(emd);

        var input = new ExportPart<T>(emd, name);
        return input;

    }
}

public class ExportMetaData<T>
{
    public string Name { get; set; }
    public string Label { get; set; }
    public string NumberFormat { get; set; }

    // just ready this in case EPPlus can compute column width in the future
    // public bool AutoFit { get; set; }

    public System.Func<T, object> ValueReplacer { get; set; }
}


public class ExportPart<T>
{
    ExportMetaData<T> _emd;

    public ExportPart(ExportMetaData<T> exportMetaData, string name)
    {
        _emd = exportMetaData;
        _emd.Name = name;
    }

    public ExportPart<T> NumberFormat(string format)
    {
        _emd.NumberFormat = format;
        return this;
    }

    public ExportPart<T> Label(string label)
    {
        _emd.Label = label;
        return this;
    }

    public ExportPart<T> ValueReplacer(System.Func<T, object> valueReplacer)
    {
        _emd.ValueReplacer = valueReplacer;
        return this;
    }
}


// Should I call this ExcelResultFromListFactory?
public static class ExcelResultFromList
{
    public static ExcelResultFromList<T> Create<T>(System.Collections.Generic.IEnumerable<T> list, string filename, System.Action<ExcelMapping<T>> mapAction)
    {
        var e = new ExcelMapping<T>();
        var r = new ExcelResultFromList<T>(list) { FileName = filename, ExcelMapping = e };
        mapAction(e);
        return r;
    }
}


public class ExcelResultFromList<T> : ExcelResult
{

    public ExcelMapping<T> ExcelMapping { get; set; }

    public System.Collections.Generic.IEnumerable<T> _list;


    public ExcelResultFromList(System.Collections.Generic.IEnumerable<T> list)
    {
        _list = list;
    }


    public override void ExecuteResult(System.Web.Mvc.ControllerContext context)
    {
        ExcelPackage = new OfficeOpenXml.ExcelPackage();

        OfficeOpenXml.ExcelWorksheet sheet = ExcelPackage.Workbook.Worksheets.Add("Export");



        int col = 0;
        foreach (ExportMetaData<T> emd in ExcelMapping.ExportList)
        {
            int ordinal = ++col;
            sheet.Cells[1, ordinal].Value = emd.Label ?? emd.Name;
            OfficeOpenXml.ExcelColumn ec = sheet.Column(ordinal);

            if (!string.IsNullOrEmpty(emd.NumberFormat))
                ec.Style.Numberformat.Format = emd.NumberFormat;


            sheet.Cells[2, ordinal].LoadFromCollection(_list.Select(y =>
                new
                {
                    Value = emd.ValueReplacer == null ? GetPropValue(y, emd.Name) : emd.ValueReplacer(y)
                }));
        }


        base.ExecuteResult(context);
    }


    // In this age of stackoverflow, who needs MSDN?
    // http://stackoverflow.com/questions/1196991/get-property-value-from-string-using-reflection-in-c-sharp
    static object GetPropValue(object src, string propName)
    {
        return src.GetType().GetProperty(propName).GetValue(src, null);
    }
}


// We can t make an apple pie from scratch, some ingredients have to come from somewhere:
// PropertyPathVisitor sourced from: http://www.thomaslevesque.com/2010/10/03/entity-framework-using-include-with-lambda-expressions/
namespace ExpressionGetter
{

    class PropertyPathVisitor : System.Linq.Expressions.ExpressionVisitor
    {
        private System.Collections.Generic.Stack<string> _stack;

        public string GetPropertyPath(System.Linq.Expressions.Expression expression)
        {
            _stack = new System.Collections.Generic.Stack<string>();
            Visit(expression);
            return _stack
                .Aggregate(
                    new System.Text.StringBuilder(),
                    (sb, name) =>
                        (sb.Length > 0 ? sb.Append(".") : sb).Append(name))
                .ToString();
        }



        protected override System.Linq.Expressions.Expression VisitMember(System.Linq.Expressions.MemberExpression expression)
        {
            if (_stack != null)
                _stack.Push(expression.Member.Name);
            return base.VisitMember(expression);
        }


    }

}


public class ExcelResult : System.Web.Mvc.ActionResult
{

    public OfficeOpenXml.ExcelPackage ExcelPackage { get; set; }
    public string FileName { get; set; }


    public override void ExecuteResult(System.Web.Mvc.ControllerContext context)
    {
        context.HttpContext.Response.AppendHeader("Content-type", "application/vnd.ms-excel");
        context.HttpContext.Response.AppendHeader("Content-disposition", string.Format("attachment; filename={0}.xls", FileName));


        byte[] a = ExcelPackage.GetAsByteArray();
        context.HttpContext.Response.OutputStream.Write(a, 0, a.Length);
    }
}

Happy Coding! ツ

Saturday, December 8, 2012

Query SARGability

A colleague asked how to select from two tables dynamically, something along this line(question was not exactly phrase as the following):


DECLARE @tableToSelect CHAR(1) = 'y';
select * from @tableToSelect where a < 100;   


If that is even possible, it would be a problem if the similar columns are differently named on the two tables, say PersonID, MencschID (German for PersonID). This can not select all the persons from the American tables:
select * from @tableToSelect where MenschID < 100;




I suggested him this:


WITH x AS
(
    SELECT a,b FROM dbo.t
    WHERE @tableToSelect = 't'
    UNION ALL    
    SELECT c,d FROM dbo.y    
    WHERE @tableToSelect = 'y'
)
SELECT * FROM x WHERE a < 100;


A discerning programmer that he is, he quizzed me if that would result to inefficient query. I like that he posed that question and wanted his code to be performant.


If he had asked me that question when I was just a starting developer, I would concur with him. I would naturally assume that it's not efficient to union the tables and filtering it further. I would assume that it would be better if the rows are filtered right from the root source, as illustrated below, and thus enabling both queries of the UNIONed queries to use the available index:


SELECT a,b
FROM t
WHERE @tableToSelect = 't' and a < 100
 
UNION all
 
SELECT c,d
FROM y
WHERE @tableToSelect = 'y' AND c < 100;



Fortunately for us, internet is a wonderful place; an eon ago, I stumble upon an article that says RDBMS doesn't short-circuit conditions: http://weblogs.sqlteam.com/mladenp/archive/2008/02/25/How-SQL-Server-short-circuits-WHERE-condition-evaluation.aspx


So this would result to an error (Conversion failed when converting date and/or time from character string):

SELECT   *
FROM     t1
WHERE    ISDATE(val) = 1
         AND CONVERT(DATETIME, val) < GETDATE();



If we try to fool the RDBMS by eagerly filtering the valid dates first, this would still not work, this will still result to conversion error. A proof that WITH or any form of re-arranging the query doesn't eagerly execute the query.


WITH x AS
(
      SELECT   *
      FROM     t1
      WHERE    ISDATE(val) = 1
)
SELECT *
FROM x    
WHERE CONVERT(DATETIME, val) < GETDATE();


That means, the conditions' execution order is not executed based on how you arrange your query. The outer query's conditions could be mixed with the inner query's condition by your RDBMS. Armed with that knowledge in mind, the following two queries are executed similarly:


SELECT *
FROM t
WHERE @tableToSelect = 't' and a < 100
 
UNION all
 
SELECT *
FROM y
WHERE @tableToSelect = 'y' AND c < 100;
 

WITH x AS
(
    SELECT a,b FROM dbo.t
    WHERE @tableToSelect = 't'
    UNION ALL    
    SELECT c,d FROM dbo.y    
    WHERE @tableToSelect = 'y'
)
SELECT * FROM x WHERE a < 100;




That is, the second query(CTE) is expanded to the same query as the first query; thus, the second query's a < 100 expression utilizes all the available indexes on both tables, making the query performant. Given that they are semantically the same, it's better to use the second query as it's easier to maintain, the query's condition is just placed on one location only, there's no code duplication involved. Some shun the table-deriving or CTE approach, as they think enclosing the query on CTE or table-deriving it would deprive the expression a < 100 the SARGability it needed; this is not true, CTE-using queries can still use the available indexes on both tables.



Both queries have exactly the same identical query execution plan:







Here's the supporting DDL:


SET NOCOUNT ON;

CREATE TABLE t(a INT, b INT);
CREATE TABLE y(c INT, d INT);

DECLARE @i INT;

SET @i = 0;
WHILE @i < 100000 BEGIN
    INSERT INTO t(a,b) VALUES(@i,0);    
SET @i = @i + 1;
END;

INSERT INTO y(c,d) SELECT a,b FROM t;
CREATE INDEX ux_t ON t(a);
CREATE INDEX ux_y ON y(c);

SET NOCOUNT OFF;



If you are a keen observer, you'll ask, what will happen to the query with the date detection in it? How to prevent the query from executing the conversion if the field is not a date? We can really do short-circuit in SQL Server explicitly, but that would entails using CASE WHEN, and that would make your query not being SARGable. Here's the short-circuited query:


SELECT *
FROM t1
WHERE CASE WHEN ISDATE(val) = 1 AND CONVERT(DATETIME, val) < GETDATE() THEN 1 END = 1



Another approach, is to use an optimization fence on ISDATE. This way, SQL Server don't need to merge the ISDATE condition with CONVERT, avoiding the conversion failed error.

with x as
(
      SELECT   TOP 4000000000 *
      FROM     t1
      WHERE    ISDATE(val) = 1
)
SELECT *
FROM x    
WHERE CONVERT(DATETIME, val) < GETDATE();
So here's the performance of a non-SARGable query:


DECLARE @tableToSelect CHAR(1) = 'y';

-- select * from @tableToSelect where a < 100;


SELECT a,b
FROM t
WHERE case when @tableToSelect = 't' AND a < 100 then 1 end = 1
 
UNION all
 
SELECT c,d
FROM y
WHERE case when @tableToSelect = 'y' AND c < 100 then 1 end = 1;
 

WITH x AS
(
    SELECT a,b FROM dbo.t
    WHERE @tableToSelect = 't'
    UNION ALL    
    SELECT c,d FROM dbo.y    
    WHERE @tableToSelect = 'y'
)
SELECT * FROM x WHERE a < 100;
As we can see the non-SARGable query is slow compared to the SARGable one. non-SARGable query has a cost of 81% against 19% of SARGable one



That's it, we should strive to make our query use our tables' indexes



Happy Coding! ツ

Armor-wielding shortcut with ZenCoding

When was the last time you have a nerdgasm? Was it since you last saw Iron Man's trailer where you've seen his suitcase armor expanded to an Iron Man suit and automatically costumed(armed?) him? Was it since you first learned Linq/lambda and all the expressiveness, succinctness and slickness you can accomplish with it?



Wow, that was so 3 years ago! In internet time it's an eternity! It's time to rectify that long drought. There are times we are in a Zen-like state (a.k.a. in the zone), wherein the code to implement something are all on your head already, your project is virtually done, ready to be coded/typed; and the only thing that is a bottleneck to implement the app is the interface between you and the computer, is the keyboard, is the typing.


With ZenCoding, typing humongous HTMLs off the top of your head will be a thing of the past. Given the following tags..



<div id="page">
    <div class="logo"></div>
    <ul id="navigation">
        <li class="navitem"></li>
        <li class="navitem"></li>
        <li class="navitem"></li>
        <li class="navitem"></li>
        <li class="navitem"></li>
        <li class="navitem"></li>
        <li class="navitem"></li>
    </ul>
</div>

..you can type that automatically with ease with ZenCoding, just type the following (CSS-like syntax), then press the tab key(on most editors it's tab key, on Visual Studio press Alt+Z):

div#page>div.logo+ul#navigation>li.navitem*7


Neat isn't it? Tony Stark will be fuming with envy when he'll know that his suitcase armor is just a one-trick pony compared to your ZenCoding armor. How about the following contruct?

div#menu>table>tr>td*7>a.nav


That expands to this:



<div id="menu">
    <table>
        <tr>
            <td><a href="" class="nav"></a></td>
            <td><a href="" class="nav"></a></td>
            <td><a href="" class="nav"></a></td>
            <td><a href="" class="nav"></a></td>
            <td><a href="" class="nav"></a></td>
            <td><a href="" class="nav"></a></td>
            <td><a href="" class="nav"></a></td>
        </tr>
    </table>
</div>


And when you want to make multiple tr tags with multiple td tags with that construct, you already know the drill ;-)


With ZenCoding, every ZenCoding shortcut are an armor ready to spring from the master's fingertips and empowers the master and protects the people


Get the ZenCoding at: http://visualstudiogallery.msdn.microsoft.com/924090a6-1177-4e81-96a3-e929d7193130

Happy Coding! ツ

Monday, December 3, 2012

Sample Fluent API barebone code

using System;
using System.Collections.Generic;

using System.Linq;
using System.Text;
using System.Linq.Expressions;




namespace Sample
{
    using DomainToInputMappings;
    
    internal class Program
    {
        private static void Main(string[] args)
        {
            var x = new FlightInput();
            Console.ReadKey();
        }
    }
}


// NHibernate can use these domain classes directly:
namespace DomainClasses
{
    public class Flight
    {
        public virtual Country Country { get; set; }
        public virtual City City { get; set; }
        public virtual int StayDuration { get; set; }
    }
    
    public class Country
    {
        public virtual string CountryCode { get; set; }
        public virtual string CountryName { get; set; }
        public virtual int Population { get; set; }
    }
    
    public class City
    {
        public virtual Country Country { get; set; }
        
        public virtual int CityID { get; set; }
        public virtual string CityName { get; set; }
    }
    
}

namespace DomainToInputMappings
{
    using DomainClasses;
    using InputMapper;
    using FinderControls;
    
    
    // On some systems, we don't directly map the domain classes to input,
    // should flatten the domain classes to DTO (e.g. x.Country.CountryCode to x.CountryCode) first,
    // then map the input to the DTO instead,
    // so it's easier and lighter(CountryName and Population won't be transferred) to transfer
    // and use the object across the wire. e.g. Silverlight, jQuery ajax, etc  
    class FlightInput : InputMap<Flight>
    {
        public FlightInput()
        {
            Input(x => x.Country.CountryCode)
                .DisplayWidth(200)
                    .Color(ConsoleColor.Blue)
                    .UseFinder<CountryFinder>().SelectedID(x => x.SelectedCountryCode);
            
            
            
            // The advantage of fluent API, aside from there's autocomplete,
            // we don't need to do stringly-typed approach when referring to the property of an object,
            // we can refer to the property in a strongly-typed manner (e.g. x.Country.CountryCode).
            // With attributes-based API, we have to do this instead:
            
            // Compilers can't catch error if you misspelled Country.ConutryCode if you make stringly-typed API
            // [DisplayWidth(200)]
            // [Color(KnownColor.Blue)]
            // [UseFinder(typeof(CityFinder), SelectedID = "SelectedCityID", CascadingField = "Country.CountryCode")]
            
            
            Input(x => x.City.CityID)
                .DisplayWidth(200)
                    .Color(ConsoleColor.Blue)
                    .UseFinder<CityFinder>().SelectedID(x => x.SelectedCityID).CascadingField(x => x.Country.CountryCode);
            
            Input(x => x.StayDuration)
                .DisplayWidth(100)
                    .Color(ConsoleColor.Green)
                    .UseSpinner(1, 10);
        }
    }
    
}


namespace FinderControls
{
    public class CountryFinder
    {
        public int SelectedCountryCode { get; set; }
        public bool MultiSelect { get; set; }
    }
    
    public class CityFinder
    {
        public int SelectedCityID { get; set; }
        public bool MultiSelect { get; set; }
    }   
}




namespace InputMapper
{
    using ExpressionGetter;
    public abstract class InputMap<T>
    {
        public InputPart<T> Input<TProp>(Expression<Func<T, TProp>> p)
        {
            Console.WriteLine(new PropertyPathVisitor().GetPropertyPath(p));
            
            
            var inputPart = new InputPart<T>();
            return inputPart;
        }
    }
    
    
    public class InputPart<T>
    {
        public InputPart<T> DisplayWidth(int width)
        {
            return this;
        }
        
        public InputPart<T> Color(ConsoleColor color)
        {
            return this;
        }
        
        public FinderPart<T, TFinder> UseFinder<TFinder>()
        {
            return new FinderPart<T, TFinder>();
        }
        
        
        public InputPart<T> UseSpinner(int from, int to)
        {
            return this;
        }
    }
    
    public class FinderPart<T, TFinder>
    {
        public FinderPart<T, TFinder> SelectedID<TFinderProp>(Expression<Func<TFinder, TFinderProp>> x)
        {
            return this;
        }
        
        public FinderPart<T, TFinder> CascadingField<TProp>(Expression<Func<T, TProp>> x)
        {
            return this;
        }
    }
}

namespace ExpressionGetter
{
    // We can’t make an apple pie from scratch, some ingredients have to come from somewhere:
    
    // PropertyPathVisitor sourced from: http://www.thomaslevesque.com/2010/10/03/entity-framework-using-include-with-lambda-expressions/
    class PropertyPathVisitor : ExpressionVisitor
    {
        private Stack<string> _stack;
        
        public string GetPropertyPath(Expression expression)
        {
            _stack = new Stack<string>();
            Visit(expression);
            return _stack
                .Aggregate(
                    new StringBuilder(),
                    (sb, name) =>
                    (sb.Length > 0 ? sb.Append(".") : sb).Append(name))
                    .ToString();
        }
        
        
        
        protected override Expression VisitMember(MemberExpression expression)
        {
            if (_stack != null)
                _stack.Push(expression.Member.Name);
            return base.VisitMember(expression);
        }
        
        
    }
    
}


Rationale for fluent-based API: http://www.ienablemuch.com/2012/11/fluent-based-apis.html

Saturday, December 1, 2012

Dream Setup

We all have our own dream setup for development machine

My dream setup is more on software stack though rather than on hardware:

  • AngularJS - MVC on client-side instead of on server-side (e.g. ASP.NET MVC)
  • ServiceStack - .NET REST API
  • ToTheEfnhX - Everyone are self-patronizing of their self-written repository component :p
  • DitTO - Everyone are self-patronizing of their self-written bi-directional domain-classes-to-DTO-classes component too :p
  • Ninject - Dependency injection component, for wiring repository component against the ORM
  • NHibernate - ORM - maps the domain classes to the database. Glad to know that the company uses NHibernate
  • Fluent NHibernate - fluent approach for setting up the mapping between NHibernate and database
  • Redis - caching provider for NHibernate
  • Postgres - database

  • Moq - for mocking object for unit testing
  • Microsoft Test if using Visual Studio - not a dream setup, but this is good enough for unit testing
  • NUnit - unit testing for C# if using MonoDevolop instead of Visual Studio
  • WatiN - For doing web application testing
  • Jasmine - unit testing for Javascript