Example #1
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;
        }
        /// <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;
        }