public virtual string Dump()
        {
            var sb = new StringBuilder();

            ActiveRecordModel model = ActiveRecordModel.GetModel(typeof(T));

            sb.Append(model.Type.Name);
            sb.Append(" { ");

            if (model.PrimaryKey != null)
            {
                sb.AppendFormat("{0} = '{1}'; ", model.PrimaryKey.Property.Name, model.PrimaryKey.Property.GetValue(this, null));
            }

            DumpProperties(sb, this, null, model.Properties);

            foreach (NestedModel nm in model.Components)
            {
                object n = nm.Property.GetValue(this, null);
                if (n == null)
                {
                    sb.AppendFormat("{0}.* = (null); ", nm.Property.Name);
                }
                else
                {
                    DumpProperties(sb, n, nm, nm.Model.Properties);
                }
            }
            sb.Append("}");

            return(sb.ToString());
        }
Exemple #2
0
        protected virtual ActionParameterModel GetFetchParameter(ActionParameterModel originalParam,
                                                                 ARFetchAttribute fetchAttribute)
        {
            Type arType  = originalParam.ParamInfo.ParameterType;
            var  arModel = ActiveRecordModel.GetModel(arType);

            if (arModel == null)
            {
                return(originalParam);
            }
            if (arModel.PrimaryKey == null)
            {
                return(originalParam);
            }

            string paramName = fetchAttribute.RequestParameterName;

            object paramValue = null;

            if (originalParam.Value != null)
            {
                paramValue = arModel.PrimaryKey.Property.GetValue(originalParam.Value, null);
            }

            if (paramValue == null)
            {
                return(originalParam);
            }

            return(new ActionParameterModel(originalParam.ParamInfo, paramName, paramValue));
        }
Exemple #3
0
        public void DiscriminatorUse()
        {
            XmlGenerationVisitor xmlVisitor = new XmlGenerationVisitor();

            xmlVisitor.CreateXml(ActiveRecordModel.GetModel(typeof(PersistedRule)));
            String xml = xmlVisitor.Xml;

            String expected =
                "<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n" +
                "<hibernate-mapping  auto-import=\"true\" default-lazy=\"false\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:nhibernate-mapping-2.2\">\r\n" +
                "  <class name=\"Castle.ActiveRecord.Tests.Model.RulesModel.PersistedRule, Castle.ActiveRecord.Tests\" table=\"PersistedRule\" discriminator-value=\"0\" lazy=\"false\">\r\n" +
                "    <id name=\"Id\" access=\"property\" column=\"Id\" type=\"Int32\" unsaved-value=\"0\">\r\n" +
                "      <generator class=\"native\">\r\n" +
                "      </generator>\r\n" +
                "    </id>\r\n" +
                "    <discriminator column=\"discriminator\" />\r\n" +
                "    <property name=\"Count\" access=\"property\" type=\"Int32\">\r\n" +
                "      <column name=\"Count\" />\r\n" +
                "    </property>\r\n" +
                "    <subclass name=\"Castle.ActiveRecord.Tests.Model.RulesModel.WorkDaysRules, Castle.ActiveRecord.Tests\" discriminator-value=\"2\" lazy=\"false\">\r\n" +
                "      <property name=\"Name\" access=\"property\" type=\"String\">\r\n" +
                "        <column name=\"Name\" />\r\n" +
                "      </property>\r\n" +
                "      <property name=\"Days\" access=\"property\" type=\"Int32\">\r\n" +
                "        <column name=\"Days\" />\r\n" +
                "      </property>\r\n" +
                "    </subclass>\r\n" +
                "  </class>\r\n" +
                "</hibernate-mapping>\r\n";;

            Assert.AreEqual(expected, xml);
        }
        protected internal static bool Exists(Type t, object pk, ICriterion criteria)
        {
            PrimaryKeyModel pkModel = ActiveRecordModel.GetModel(t).PrimaryKey;
            string          pkField = pkModel.Property.Name;
            object          o       = FindFirst(t, Expression.And(criteria, Expression.Not(Expression.Eq(pkField, pk))));

            return(o != null);
        }
Exemple #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CountQuery"/> class.
        /// </summary>
        /// <param name="targetType">The target type.</param>
        /// <param name="filter">The filter.</param>
        /// <param name="parameters">The parameters.</param>
        public CountQuery(Type targetType, string filter, params object[] parameters)
            : base(targetType, " WHERE " + filter, parameters)
        {
            ActiveRecordBase.EnsureInitialized(targetType);
            var    model    = ActiveRecordModel.GetModel(targetType);
            string typeName = model.UseAutoImport ? targetType.Name : targetType.FullName;

            Query = "SELECT COUNT(*) FROM " + typeName + Query;
        }
        public void ArIssue274_CanConnectGenericJoinedBase()
        {
            ActiveRecordStarter.Initialize(GetConfigSource(),
                                           typeof(GenBaseJoinedClass <>),
                                           typeof(GenIntermediateClass <>),
                                           typeof(GenGrandsonClass));

            Assert.That(ActiveRecordModel.GetModel(typeof(GenBaseJoinedClass <>)),
                        Is.EqualTo(ActiveRecordModel.GetModel(typeof(GenGrandsonClass)).Parent));
        }
        internal static IEnumerable GetNestedPropertiesToValidate(object instance)
        {
            Type type            = instance.GetType();
            ActiveRecordModel me = ActiveRecordModel.GetModel(type);

            foreach (NestedModel component in me.Components)
            {
                yield return(component.Property);
            }
        }
        public void CanConnectGrandChildren()
        {
            ActiveRecordStarter.Initialize(GetConfigSource(),
                                           typeof(ClassDiscriminatorA),
                                           typeof(DiscriminatorGrandchild),
                                           typeof(ClassDiscriminatorParent));

            Assert.AreEqual(
                ActiveRecordModel.GetModel(typeof(ClassDiscriminatorA)),
                ActiveRecordModel.GetModel(typeof(DiscriminatorGrandchild)).Parent
                );
        }
Exemple #9
0
        private ActiveRecordModel GetARModel()
        {
            ActiveRecordModel model = ActiveRecordModel.GetModel(modelType);

            if (model == null)
            {
                throw new ScaffoldException("Specified type isn't an ActiveRecord type or the ActiveRecord " +
                                            "framework wasn't started properly. Did you forget about the Initialize method?");
            }

            return(model);
        }
Exemple #10
0
        private ActiveRecordModel GetARModel()
        {
            var foundModel = ActiveRecordModel.GetModel(modelType);

            if (foundModel == null)
            {
                throw new ScaffoldException("Specified type is not an ActiveRecord type or the ActiveRecord " +
                                            "framework was not started properly. Did you forget to invoke ActiveRecordStarter.Initialize() ?");
            }

            return(foundModel);
        }
Exemple #11
0
        protected override object CreateInstance(Type instanceType, String paramPrefix, NameValueCollection paramsList)
        {
            object instance = null;

            bool shouldLoad = autoLoad || paramsList[paramPrefix + AutoLoadAttribute] == Yes;

            if (shouldLoad && paramsList[paramPrefix + AutoLoadAttribute] == No)
            {
                shouldLoad = false;
            }

            if (shouldLoad)
            {
                if (instanceType.IsArray)
                {
                    throw new RailsException("ARDataBinder autoload does not support arrays");
                }

                if (!typeof(ActiveRecordBase).IsAssignableFrom(instanceType))
                {
                    throw new RailsException("ARDataBinder autoload only supports classes that inherit from ActiveRecordBase");
                }

                ActiveRecordModel model = ActiveRecordModel.GetModel(instanceType);

                // NOTE: as of right now we only support one PK
                if (model.Ids.Count == 1)
                {
                    PrimaryKeyModel pkModel = model.Ids[0] as PrimaryKeyModel;

                    string propName    = pkModel.Property.Name;
                    string paramListPk = (paramPrefix == String.Empty) ? propName : paramPrefix + "." + propName;
                    string propValue   = paramsList.Get(paramListPk);

                    if (propValue != null)
                    {
                        object id = ConvertUtils.Convert(pkModel.Property.PropertyType, propValue, propName, null, null);
                        instance = SupportingUtils.FindByPK(instanceType, id);
                    }
                    else
                    {
                        throw new RailsException("ARDataBinder autoload failed as element {0} doesn't have a primary key {1} value", paramPrefix, propName);
                    }
                }
            }
            else
            {
                instance = base.CreateInstance(instanceType, paramPrefix, paramsList);
            }

            return(instance);
        }
        public void PluralizationOff()
        {
            XmlConfigurationSource config = (XmlConfigurationSource)GetConfigSource();

            config.PluralizeTableNames = false;

            ActiveRecordStarter.Initialize(config, typeof(Post), typeof(Blog), typeof(Snippet), typeof(Octopus));

            Assert.AreEqual("PostTable", ActiveRecordModel.GetModel(typeof(Post)).ActiveRecordAtt.Table);
            Assert.AreEqual("BlogTable", ActiveRecordModel.GetModel(typeof(Blog)).ActiveRecordAtt.Table);
            Assert.AreEqual("Snippet", ActiveRecordModel.GetModel(typeof(Snippet)).ActiveRecordAtt.Table);
            Assert.AreEqual("Octopus", ActiveRecordModel.GetModel(typeof(Octopus)).ActiveRecordAtt.Table);
        }
Exemple #13
0
        private bool CheckModelAndKeyAreAccessible(Type type)
        {
            ActiveRecordModel otherModel = ActiveRecordModel.GetModel(type);

            PrimaryKeyModel keyModel = ObtainPKProperty(otherModel);

            if (otherModel == null || keyModel == null)
            {
                return(false);
            }

            return(true);
        }
Exemple #14
0
        protected void SaveManyMappings(object instance, ActiveRecordModel model, DataBindContext context)
        {
            foreach (HasManyModel hasManyModel in model.HasMany)
            {
                if (hasManyModel.HasManyAtt.Inverse)
                {
                    continue;
                }
                if (hasManyModel.HasManyAtt.RelationType != RelationType.Bag &&
                    hasManyModel.HasManyAtt.RelationType != RelationType.Set)
                {
                    continue;
                }

                ActiveRecordModel otherModel = ActiveRecordModel.GetModel(hasManyModel.HasManyAtt.MapType);

                PrimaryKeyModel keyModel = ARCommonUtils.ObtainPKProperty(otherModel);

                if (otherModel == null || keyModel == null)
                {
                    continue;                     // Impossible to save
                }

                CreateMappedInstances(instance, hasManyModel.Property, keyModel, otherModel, context);
            }

            foreach (HasAndBelongsToManyModel hasManyModel in model.HasAndBelongsToMany)
            {
                if (hasManyModel.HasManyAtt.Inverse)
                {
                    continue;
                }
                if (hasManyModel.HasManyAtt.RelationType != RelationType.Bag &&
                    hasManyModel.HasManyAtt.RelationType != RelationType.Set)
                {
                    continue;
                }

                ActiveRecordModel otherModel = ActiveRecordModel.GetModel(hasManyModel.HasManyAtt.MapType);

                PrimaryKeyModel keyModel = ARCommonUtils.ObtainPKProperty(otherModel);

                if (otherModel == null || keyModel == null)
                {
                    continue;                     // Impossible to save
                }

                CreateMappedInstances(instance, hasManyModel.Property, keyModel, otherModel, context);
            }
        }
Exemple #15
0
        public String CreateControl(ActiveRecordModel model, BelongsToModel belongsToModel, object instance)
        {
            stringBuilder.Length = 0;

            PropertyInfo prop = belongsToModel.Property;

            ActiveRecordModel otherModel = ActiveRecordModel.GetModel(belongsToModel.BelongsToAtt.Type);

            PrimaryKeyModel keyModel = ObtainPKProperty(otherModel);

            if (otherModel == null || keyModel == null)
            {
                return("Model not found or PK not found");
            }

            object[] items = CommonOperationUtils.FindAll(otherModel.Type);

            String propName = String.Format("{0}.{1}", prop.Name, keyModel.Property.Name);

            object value = null;

            if (instance != null)
            {
                if (model.IsNestedType)
                {
                    instance = model2nestedInstance[model];
                }

                if (instance != null)
                {
                    value = prop.GetValue(instance, null);
                }
            }

            stringBuilder.Append(LabelFor(propName, prop.Name + ": &nbsp;"));

            stringBuilder.Append(Select(propName));

            if (!belongsToModel.BelongsToAtt.NotNull)
            {
                stringBuilder.Append(CreateOption("Empty", 0));
            }

            stringBuilder.Append(CreateOptionsFromArray(items, null, keyModel.Property.Name, value));

            stringBuilder.Append(EndSelect());

            return(stringBuilder.ToString());
        }
        public object FetchActiveRecord(ParameterInfo param,
                                        ARFetchAttribute attr,
                                        IRequest request,
                                        IDictionary <string, object> customActionParameters)
        {
            var type = param.ParameterType;

            var isArray = type.IsArray;

            if (isArray)
            {
                type = type.GetElementType();
            }

            var model = ActiveRecordModel.GetModel(type);

            if (model == null)
            {
                throw new MonoRailException(String.Format("'{0}' is not an ActiveRecord " +
                                                          "class. It could not be bound to an [ARFetch] attribute.", type.Name));
            }

            if (model.CompositeKey != null)
            {
                throw new MonoRailException("ARFetch only supports single-attribute primary keys");
            }

            var webParamName = attr.RequestParameterName ?? param.Name;

            if (!isArray)
            {
                var value = GetParameterValue(webParamName, customActionParameters, request);
                return(LoadActiveRecord(type, value, attr, model));
            }

            var pks = GetParameterValues(webParamName, customActionParameters, request);

            var objs = Array.CreateInstance(type, pks.Length);

            for (var i = 0; i < objs.Length; i++)
            {
                objs.SetValue(LoadActiveRecord(type, pks[i], attr, model), i);
            }

            return(objs);
        }
Exemple #17
0
        protected override void AfterBinding(object instance, String paramPrefix, DataBindContext context)
        {
            // Defensive programming
            if (instance == null)
            {
                return;
            }

            ActiveRecordModel model = ActiveRecordModel.GetModel(instance.GetType());

            if (model == null)
            {
                return;
            }

            SaveManyMappings(instance, model, context);
        }
        /// <summary>
        /// Obtém o tamanho máximo de um campo no banco de dados.
        /// </summary>
        /// <param name="table">A tabela</param>
        /// <param name="field">O campo</param>
        /// <returns>
        /// O tamanho máximo do campo, ou
        /// <c>null</c> caso não seja
        /// possível obter o tamanho máximo.
        /// </returns>
        public NullableInt32 MaxLength(string table, string field)
        {
            Type t = GetModelType(table);

            if (t == null)
            {
                return(null);
            }

            EnsureMetadataCache(t);

            ActiveRecordModel model = ActiveRecordModel.GetModel(t);

            if (model == null)
            {
                return(null);
            }

            IDictionary type2len = (IDictionary)type2lengths[t];

            if (type2len == null)
            {
                lock (type2lengths.SyncRoot)
                {
                    type2len = new HybridDictionary(true);

                    string physicalTableName = model.ActiveRecordAtt.Table;

                    foreach (PropertyModel p in model.Properties)
                    {
                        string physicalColumnName = p.PropertyAtt.Column;
                        type2len.Add(p.Property.Name, mdCache.MaxLength(physicalTableName, physicalColumnName));
                    }

                    type2lengths[t] = type2len;
                }
            }

            if (!type2len.Contains(field))
            {
                return(null);
            }

            return((int)type2len[field]);
        }
        internal new void EnsureInitialized(Type targetType)
        {
            var holder = ActiveRecordMediator.GetSessionFactoryHolder();

            if (holder == null)
            {
                String message = String.Format("An ActiveRecord class ({0}) was used but the framework seems not " +
                                               "properly initialized. Did you forget about ActiveRecordStarter.Initialize() ?",
                                               targetType.FullName);
                throw new ActiveRecordException(message);
            }
            if (targetType != typeof(ActiveRecordBase) && ActiveRecordModel.GetModel(targetType) == null)
            {
                String message = String.Format("You have accessed an ActiveRecord class that wasn't properly initialized. " +
                                               "There are two possible explanations: that the call to ActiveRecordStarter.Initialize() didn't include {0} class, or that {0} class is not decorated with the [ActiveRecord] attribute.",
                                               targetType.FullName);
                throw new ActiveRecordException(message);
            }
        }
 /// <summary>
 /// for joined subclasses HasMany properties doesn't include the ones of the parent class
 /// so we need to check them recursively
 /// </summary>
 protected bool FindPropertyInHasMany(ActiveRecordModel model, string propertyName,
                                      ref Type foundType, ref ActiveRecordModel foundModel)
 {
     foreach (var hasManyModel in model.HasMany)
     {
         // Inverse=true relations will be ignored
         if (hasManyModel.Property.Name == propertyName && !hasManyModel.HasManyAtt.Inverse)
         {
             foundType  = hasManyModel.HasManyAtt.MapType;
             foundModel = ActiveRecordModel.GetModel(foundType);
             return(true);
         }
     }
     if (model.IsJoinedSubClass || model.IsDiscriminatorSubClass)
     {
         return(FindPropertyInHasMany(model.Parent, propertyName, ref foundType, ref foundModel));
     }
     return(false);
 }
Exemple #21
0
        private object FetchActiveRecord(ParameterInfo param, ARFetchAttribute attr, IRequest request)
        {
            Type type = param.ParameterType;

            bool isArray = type.IsArray;

            if (isArray)
            {
                type = type.GetElementType();
            }

            ActiveRecordModel model = ActiveRecordModel.GetModel(type);

            if (model == null)
            {
                throw new RailsException(String.Format("'{0}' is not an ActiveRecord " +
                                                       "class. It could not be bound to an [ARFetch] attribute.", type.Name));
            }

            if (model.Ids.Count != 1)
            {
                throw new RailsException("ARFetch only supports single-attribute primary keys");
            }

            String webParamName = attr.RequestParameterName != null ? attr.RequestParameterName : param.Name;

            if (!isArray)
            {
                return(LoadActiveRecord(type, request.Params[webParamName], attr, model));
            }

            object[] pks = request.Params.GetValues(webParamName);

            Array objs = Array.CreateInstance(type, pks.Length);

            for (int i = 0; i < objs.Length; i++)
            {
                objs.SetValue(LoadActiveRecord(type, pks[i], attr, model), i);
            }

            return(objs);
        }
        public String CreateControl(ActiveRecordModel model, String prefix,
                                    HasAndBelongsToManyModel hasAndBelongsModel, object instance)
        {
            stringBuilder.Length = 0;

            var prop = hasAndBelongsModel.Property;

            prefix += "." + prop.Name;

            var otherModel = ActiveRecordModel.GetModel(hasAndBelongsModel.HasManyAtt.MapType);

            var keyModel = ObtainPKProperty(otherModel);

            if (otherModel == null || keyModel == null)
            {
                return("Model not found or PK not found");
            }

            var source = CommonOperationUtils.FindAll(otherModel.Type);

            stringBuilder.Append(prop.Name + ": &nbsp;");
            stringBuilder.Append("<br/>\r\n");

            IDictionary attrs = new HybridDictionary(true);

            attrs["value"] = keyModel.Property.Name;

            var list = CreateCheckboxList(prefix, source, attrs);

            foreach (var item in list)
            {
                stringBuilder.Append(list.Item());

                stringBuilder.Append(item.ToString());

                stringBuilder.Append("<br/>\r\n");
            }

            return(stringBuilder.ToString());
        }
Exemple #23
0
        public ICollection GetModelHierarchy(ActiveRecordModel model, object instance)
        {
            ArrayList list = new ArrayList();

            ActiveRecordModel hierarchy = model;

            while (hierarchy != null)
            {
                list.Add(hierarchy);

                hierarchy = ActiveRecordModel.GetModel(hierarchy.Type.BaseType);
            }

            hierarchy = model;

            while (hierarchy != null)
            {
                foreach (NestedModel nested in hierarchy.Components)
                {
                    object nestedInstance = nested.Property.GetValue(instance, null);

                    if (nestedInstance == null)
                    {
                        nestedInstance = CreationUtil.Create(nested.Property.PropertyType);
                    }

                    if (nestedInstance != null)
                    {
                        model2nestedInstance[nested.Model] = nestedInstance;
                    }

                    list.Add(nested.Model);
                }

                hierarchy = ActiveRecordModel.GetModel(hierarchy.Type.BaseType);
            }

            return(list);
        }
        protected override void PopInstance(object instance, string prefix)
        {
            var model = ActiveRecordModel.GetModel(instance.GetType());

            if (model == null && CurrentARModel != null && CurrentARModel.IsNestedType)
            {
                modelStack.Pop();
            }

            if (model != null)
            {
                var actualModel = modelStack.Pop();

                if (actualModel != model)
                {
                    throw new BindingException("Unexpected ARModel on the stack: found {0}, expecting {1}",
                                               actualModel.ToString(), model.ToString());
                }
            }

            base.PopInstance(instance, prefix);
        }
        public String CreateControl(ActiveRecordModel model, String prefix,
                                    BelongsToModel belongsToModel, object instance)
        {
            stringBuilder.Length = 0;

            var prop = belongsToModel.Property;

            prefix += "." + prop.Name;

            var otherModel = ActiveRecordModel.GetModel(belongsToModel.BelongsToAtt.Type);

            var keyModel = ObtainPKProperty(otherModel);

            if (otherModel == null || keyModel == null)
            {
                return("Model not found or PK not found");
            }

            var items = CommonOperationUtils.FindAll(otherModel.Type);

            var propName = CreatePropName(model, prefix, keyModel.Property.Name);

            stringBuilder.Append(LabelFor(propName, TextHelper.PascalCaseToWord(prop.Name) + ": &nbsp;"));

            IDictionary attrs = new HybridDictionary(true);

            attrs["value"] = keyModel.Property.Name;

            if (!belongsToModel.BelongsToAtt.NotNull)
            {
                attrs.Add("firstOption", "Empty");
                attrs.Add("firstOptionValue", "");
            }

            stringBuilder.Append(Select(propName, items, attrs));

            return(stringBuilder.ToString());
        }
        protected override void PushInstance(object instance, string prefix)
        {
            var model = ActiveRecordModel.GetModel(instance.GetType());

            if (model == null && modelStack.Count != 0)
            {
                foreach (var nestedModel in CurrentARModel.Components)
                {
                    if (string.Compare(nestedModel.Property.Name, prefix, true) == 0)
                    {
                        model = nestedModel.Model;
                        break;
                    }
                }
            }

            if (model != null)
            {
                modelStack.Push(model);
            }

            base.PushInstance(instance, prefix);
        }
Exemple #27
0
        public String CreateControl(ActiveRecordModel model, HasAndBelongsToManyModel hasAndBelongsModel, object instance)
        {
            stringBuilder.Length = 0;

            PropertyInfo prop = hasAndBelongsModel.Property;

            ActiveRecordModel otherModel = ActiveRecordModel.GetModel(hasAndBelongsModel.HasManyAtt.MapType);

            PrimaryKeyModel keyModel = ObtainPKProperty(otherModel);

            if (otherModel == null || keyModel == null)
            {
                return("Model not found or PK not found");
            }

            object container = InitializeRelationPropertyIfNull(instance, prop);

            object value = null;

            if (container != null)
            {
                value = CreateArrayFromExistingIds(keyModel, container as ICollection);
            }

            object[] items = CommonOperationUtils.FindAll(otherModel.Type, hasAndBelongsModel.HasManyAtt.Where);

            String propName = String.Format("{0}.{1}", prop.Name, keyModel.Property.Name);

            stringBuilder.Append(LabelFor(propName, prop.Name + ": &nbsp;"));
            stringBuilder.Append("<br/>");
            stringBuilder.Append(Select(propName, new DictHelper().CreateDict("size=6", "multiple")));
            stringBuilder.Append(CreateOptionsFromArray(items, null, keyModel.Property.Name, value));
            stringBuilder.Append(EndSelect());

            return(stringBuilder.ToString());
        }
 public ARLoaderEnumerator(Type arType, IEnumerable keys)
     : base(keys.GetEnumerator())
 {
     this.pkModel = ActiveRecordModel.GetModel(arType).PrimaryKey;
     this.arType  = arType;
 }
        protected override object CreateInstance(Type instanceType, String paramPrefix, Node node)
        {
            if (node == null)
            {
                throw new BindingException(
                          "Nothing found for the given prefix. Are you sure the form fields are using the prefix " +
                          paramPrefix + "?");
            }

            if (node.NodeType != NodeType.Composite)
            {
                throw new BindingException("Unexpected node type. Expecting Composite, found " + node.NodeType);
            }

            var cNode = (CompositeNode)node;

            object instance;

            var shouldLoad = autoLoad != AutoLoadBehavior.Never;

            if (autoLoad == AutoLoadBehavior.OnlyNested)
            {
                shouldLoad = StackDepth != 0;
            }

            var model = ActiveRecordModel.GetModel(instanceType);

            if (shouldLoad && model == null)             // Nested type or unregistered type
            {
                shouldLoad = false;
            }

            if (shouldLoad)
            {
                if (instanceType.IsArray)
                {
                    throw new BindingException("ARDataBinder AutoLoad does not support arrays");
                }

                PrimaryKeyModel pkModel;

                var id = ObtainPrimaryKeyValue(model, cNode, paramPrefix, out pkModel);

                if (IsValidKey(id))
                {
                    instance = FindByPrimaryKey(instanceType, id);
                }
                else
                {
                    if (autoLoad == AutoLoadBehavior.NewInstanceIfInvalidKey ||
                        (autoLoad == AutoLoadBehavior.NewRootInstanceIfInvalidKey && StackDepth == 0))
                    {
                        instance = base.CreateInstance(instanceType, paramPrefix, node);
                    }
                    else if (autoLoad == AutoLoadBehavior.NullIfInvalidKey ||
                             autoLoad == AutoLoadBehavior.OnlyNested ||
                             (autoLoad == AutoLoadBehavior.NewRootInstanceIfInvalidKey && StackDepth != 0))
                    {
                        instance = null;
                    }
                    else
                    {
                        throw new BindingException(string.Format(
                                                       "Could not find primary key '{0}' for '{1}'",
                                                       pkModel.Property.Name, instanceType.FullName));
                    }
                }
            }
            else
            {
                instance = base.CreateInstance(instanceType, paramPrefix, node);
            }

            return(instance);
        }
        object IParameterBinder.Bind(SmartDispatcherController controller, ParameterInfo parameterInfo)
        {
            var genArgs = parameterInfo.ParameterType.GetGenericArguments();

            var keyType = genArgs[0];
            var valType = genArgs[1];

            var keyModel = ActiveRecordModel.GetModel(keyType);
            var valModel = ActiveRecordModel.GetModel(valType);

            var keyPKType = keyModel == null?NormalizeNullable(keyType) : keyModel.PrimaryKey.Property.PropertyType;

            var valPKType = valModel == null?NormalizeNullable(valType) : valModel.PrimaryKey.Property.PropertyType;

            var dict = (IDictionary)Activator.CreateInstance(parameterInfo.ParameterType);

            foreach (string requestKey in controller.Params.Keys)
            {
                if (String.IsNullOrEmpty(requestKey))
                {
                    continue;
                }

                var m = expr.Match(requestKey);
                if (!m.Success)
                {
                    continue;
                }

                var keyContents = Convert.ChangeType(m.Groups[1].Value, keyPKType);
                if (keyModel != null)
                {
                    keyContents = ActiveRecordMediator.FindByPrimaryKey(keyType, keyContents);
                }

                var valContents = (object)controller.Params[requestKey];
                if (String.Empty.Equals(valContents))
                {
                    valContents = null;
                }

                if (valContents != null)
                {
                    valContents = Convert.ChangeType(valContents, valPKType);
                    if (valModel != null)
                    {
                        valContents = ActiveRecordMediator.FindByPrimaryKey(valType, valContents);
                    }
                }

                // If the value is empty and this is a ValueType, get the default value for the ValueType
                if (valContents == null && valType.IsValueType)
                {
                    valContents = Activator.CreateInstance(valType);
                }

                if (AllowDuplicates)
                {
                    dict[keyContents] = valContents;
                }
                else
                {
                    dict.Add(keyContents, valContents);
                }
            }

            return(dict);
        }