/// <summary>
        /// Deserializes the specified config.
        /// </summary>
        /// <param name="config">The config.</param>
        /// <param name="dataExchangeFactory">The data exchange factory.</param>
        /// <param name="waitResultPropertyResolution">The wait result property resolution delegate.</param>
        /// <param name="waitDiscriminatorResolution">The wait discriminator resolution.</param>
        /// <returns></returns>
        public static ResultMap Deserialize(
            IConfiguration config,
            DataExchangeFactory dataExchangeFactory,
            WaitResultPropertyResolution waitResultPropertyResolution,
            WaitDiscriminatorResolution waitDiscriminatorResolution
            )
        {
            string id         = config.Id;
            string className  = ConfigurationUtils.GetMandatoryStringAttribute(config, ConfigConstants.ATTRIBUTE_CLASS);
            string extends    = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_EXTENDS);
            string groupBy    = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_GROUPBY);
            string keyColumns = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_KEYS_PROPERTIES);
            string suffix     = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_SUFFIX, string.Empty);
            string prefix     = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_PREFIX, string.Empty);

            Type          type                   = dataExchangeFactory.TypeHandlerFactory.GetType(className);
            IDataExchange dataExchange           = dataExchangeFactory.GetDataExchangeForClass(type);
            IFactory      factory                = null;
            ArgumentPropertyCollection arguments = new ArgumentPropertyCollection();

            #region Get the constructor & associated parameters

            ConfigurationCollection constructors = config.Children.Find(ConfigConstants.ELEMENT_CONSTRUCTOR);

            if (constructors.Count > 0)
            {
                IConfiguration constructor = constructors[0];

                Type[]   argumentsType = new Type[constructor.Children.Count];
                string[] argumentsName = new string[constructor.Children.Count];

                // Builds param name list
                for (int i = 0; i < constructor.Children.Count; i++)
                {
                    argumentsName[i] = ConfigurationUtils.GetStringAttribute(constructor.Children[i].Attributes, ConfigConstants.ATTRIBUTE_ARGUMENTNAME);
                }

                // Find the constructor
                ConstructorInfo constructorInfo = GetConstructor(id, type, argumentsName);

                // Build ArgumentProperty and parameter type list
                for (int i = 0; i < constructor.Children.Count; i++)
                {
                    ArgumentProperty argumentMapping = ArgumentPropertyDeSerializer.Deserialize(
                        constructor.Children[i],
                        type,
                        constructorInfo,
                        dataExchangeFactory);

                    arguments.Add(argumentMapping);

                    if (argumentMapping.NestedResultMapName.Length > 0)
                    {
                        waitResultPropertyResolution(argumentMapping);
                    }

                    argumentsType[i] = argumentMapping.MemberType;
                }
                // Init the object factory
                factory = dataExchangeFactory.ObjectFactory.CreateFactory(type, argumentsType);
            }
            else
            {
                if (!dataExchangeFactory.TypeHandlerFactory.IsSimpleType(type) && type != typeof(DataRow))
                {
                    factory = dataExchangeFactory.ObjectFactory.CreateFactory(type, Type.EmptyTypes);
                }
            }

            #endregion

            ResultPropertyCollection properties = BuildResultProperties(
                id,
                config,
                type,
                prefix,
                suffix,
                dataExchangeFactory,
                waitResultPropertyResolution);
            Discriminator discriminator = BuildDiscriminator(config, type, dataExchangeFactory, waitDiscriminatorResolution);

            ResultMap resultMap = new ResultMap(
                id,
                className,
                extends,
                groupBy,
                keyColumns,
                type,
                dataExchange,
                factory,
                dataExchangeFactory.TypeHandlerFactory,
                properties,
                arguments,
                discriminator
                );

            return(resultMap);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Deserializes the specified config.
        /// </summary>
        /// <param name="config">The config.</param>
        /// <param name="dataExchangeFactory">The data exchange factory.</param>
        /// <param name="waitResultPropertyResolution">The wait result property resolution delegate.</param>
        /// <param name="waitDiscriminatorResolution">The wait discriminator resolution.</param>
        /// <returns></returns>
        public static ResultMap Deserialize(
            IConfiguration config,
            DataExchangeFactory dataExchangeFactory,
            WaitResultPropertyResolution waitResultPropertyResolution,
            WaitDiscriminatorResolution waitDiscriminatorResolution
            )
        {
            /*resultMaps子节点信息格式
             *   <resultMap id="account-result-constructor"  class="Account" >
             *      <constructor>
             *          <argument argumentName="identifiant"	column="Account_ID"/>
             *          <argument argumentName="firstName"    column="Account_FirstName"/>
             *          <argument argumentName="lastName"     column="Account_LastName"/>
             *   </constructor>
             *   <result property="EmailAddress" column="Account_Email" nullValue="*****@*****.**"/>
             *   <result property="BannerOption" column="Account_Banner_Option" dbType="Varchar" type="bool"/>
             *   <result property="CartOption"	  column="Account_Cart_Option" typeHandler="HundredsBool"/>
             * </resultMap>
             */
            //从config中对应的resultMap节点获取其属性
            string id         = config.Id;
            string className  = ConfigurationUtils.GetMandatoryStringAttribute(config, ConfigConstants.ATTRIBUTE_CLASS);
            string extends    = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_EXTENDS);
            string groupBy    = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_GROUPBY);
            string keyColumns = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_KEYS_PROPERTIES);
            string suffix     = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_SUFFIX, string.Empty);
            string prefix     = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_PREFIX, string.Empty);

            //从工厂类的别名字典中获取
            Type type = dataExchangeFactory.TypeHandlerFactory.GetType(className);
            //根据type类型获取IDataExchange类对象
            IDataExchange dataExchange = dataExchangeFactory.GetDataExchangeForClass(type);
            IFactory      factory      = null;
            //准备存储构造函数参数argument节点信息
            ArgumentPropertyCollection arguments = new ArgumentPropertyCollection();

            #region Get the constructor & associated parameters

            //获取config下节点构造函数constructor的集合
            ConfigurationCollection constructors = config.Children.Find(ConfigConstants.ELEMENT_CONSTRUCTOR);

            if (constructors.Count > 0)
            {
                //默认获取第一个构造函数constructor节点  因为是初始化一个类  一个构造函数就足够了
                IConfiguration constructor = constructors[0];

                Type[]   argumentsType = new Type[constructor.Children.Count];
                string[] argumentsName = new string[constructor.Children.Count];

                // Builds param name list
                //argument节点的个数
                for (int i = 0; i < constructor.Children.Count; i++)
                {
                    //argumentName属性的取值
                    argumentsName[i] = ConfigurationUtils.GetStringAttribute(constructor.Children[i].Attributes, ConfigConstants.ATTRIBUTE_ARGUMENTNAME);
                }

                // Find the constructor  匹配构造函数
                ConstructorInfo constructorInfo = GetConstructor(id, type, argumentsName);

                // Build ArgumentProperty and parameter type list
                //处理构造函数的参数 每一个参数添加到arguments参数列表中
                for (int i = 0; i < constructor.Children.Count; i++)
                {
                    ArgumentProperty argumentMapping = ArgumentPropertyDeSerializer.Deserialize(
                        constructor.Children[i], //第i个Argument节点配置类
                        type,                    //当前构造函数的类
                        constructorInfo,         //当前构造函数的信息
                        dataExchangeFactory);

                    arguments.Add(argumentMapping);

                    //此处NestedResultMapName字符串应该为空
                    if (argumentMapping.NestedResultMapName.Length > 0)
                    {
                        waitResultPropertyResolution(argumentMapping);
                    }
                    //保存当前参数的类型
                    argumentsType[i] = argumentMapping.MemberType;
                }
                // Init the object factory
                //构造函数参数信息分析完成   动态初始化这个构造函数
                factory = dataExchangeFactory.ObjectFactory.CreateFactory(type, argumentsType);
            }
            else
            {
                if (!dataExchangeFactory.TypeHandlerFactory.IsSimpleType(type) && type != typeof(DataRow))
                {
                    factory = dataExchangeFactory.ObjectFactory.CreateFactory(type, Type.EmptyTypes);
                }
            }

            #endregion

            //处理result所有节点
            ResultPropertyCollection properties = BuildResultProperties(
                id,
                config,
                type,
                prefix,
                suffix,
                dataExchangeFactory,
                waitResultPropertyResolution);
            //对discriminator鉴别器的分析
            Discriminator discriminator = BuildDiscriminator(config, type, dataExchangeFactory, waitDiscriminatorResolution);

            //子节点分析完毕 将这些信息加入到resultMap父节点中
            ResultMap resultMap = new ResultMap(
                id,
                className,
                extends,
                groupBy,
                keyColumns,
                type,
                dataExchange,
                factory,
                dataExchangeFactory.TypeHandlerFactory,
                properties,
                arguments,
                discriminator
                );

            return(resultMap);
        }