public IModelBinder <TModel> Create <TModel>(params ICondition <TModel>[] conditions) where TModel : new()
        {
            var modelType = typeof(TModel);

            var readerBuilder = new ModelReaderBuilder <TModel>();
            var writerBuilder = new ModelWriterBuilder <TModel>();

            var parentProperties = new LinkedList <PropertyInfo>();

            var conditionMap = conditions.ToDictionary(x => x.GetFullParameterName(), x => x);

            Create(modelType, string.Empty, readerBuilder, writerBuilder, parentProperties, conditionMap);

            return(new ModelBinder <TModel>(readerBuilder.Compile(), writerBuilder.Compile()));
        }
        private void Create <TModel>(
            Type modelType,
            string prefix,
            ModelReaderBuilder <TModel> readerBuilder,
            ModelWriterBuilder <TModel> writerBuilder,
            LinkedList <PropertyInfo> parentProperties,
            IDictionary <string, ICondition <TModel> > conditions)
            where TModel : new()
        {
            var properties = modelType.GetProperties();

            foreach (var propertyInfo in properties)
            {
                if (Attribute.IsDefined(propertyInfo, typeof(IgnoreBindingAttribute)))
                {
                    continue;
                }

                bool isPropStatic = (propertyInfo.CanRead && propertyInfo.GetGetMethod().IsStatic) || (propertyInfo.CanWrite && propertyInfo.GetSetMethod().IsStatic);

                if (isPropStatic)
                {
                    continue;
                }

                var subParentProperties = new LinkedList <PropertyInfo>(parentProperties);
                subParentProperties.AddLast(propertyInfo);

                string fullParameterName = GetFullParameterName(subParentProperties);
                string parameterName     = GetParameterName(prefix, propertyInfo);
                DbType parameterDbType   = GetParameterDbType(propertyInfo, fullParameterName, conditions);

                if (parameterDbType != DbType.Object)
                {
                    readerBuilder.AddProperty(parameterName, fullParameterName, subParentProperties, conditions);
                    writerBuilder.AddProperty(parameterName, fullParameterName, parameterDbType, subParentProperties, conditions);
                }
                else
                {
                    var subPrefix = GetSubPrefix(prefix, propertyInfo);
                    readerBuilder.AddPropertyInitializer(subParentProperties);

                    Create(propertyInfo.PropertyType, subPrefix, readerBuilder, writerBuilder, subParentProperties, conditions);
                }
            }
        }