/// <summary>
        /// Produce a <see cref="ContractCollection"/> containing all contracts found in the provided XML <paramref name="element"/>.
        /// </summary>
        /// <param name="element">The XML element to parse.</param>
        /// <returns>A contract collection containing the contracts found in the XML element.</returns>
        /// <exception cref="ContractParseException">Parsing failed.</exception>
        public static ContractCollection FromXml(XElement element)
        {
            var bindActions = new List <Action>();

            var collection = new ContractCollection {
                AllowResolution = false
            };

            foreach (var el in element.Elements())
            {
                var id = el.Attribute("Id")?.Value;

                if (string.IsNullOrWhiteSpace(id))
                {
                    throw new ContractParseException("Contract XML element must contain a non-empty \"Id\" attribute.");
                }

                ByRefContract contract;
                switch (el.Name.LocalName)
                {
                case "ComplexRead":
                    contract = new ComplexReadContract(el, collection.ResolveReadContract, bindActions);
                    break;

                case "ComplexWrite":
                    contract = new ComplexWriteContract(el, collection.ResolveWriteContract, bindActions);
                    break;

                case "UnionRead":
                    contract = new UnionReadContract(el, collection.ResolveReadContract, bindActions);
                    break;

                case "UnionWrite":
                    contract = new UnionWriteContract(el, collection.ResolveWriteContract, bindActions);
                    break;

                case "Enum":
                    contract = new EnumContract(el);
                    break;

                default:
                    throw new ContractParseException($"Unsupported contract XML element with name \"{el.Name.LocalName}\".");
                }

                contract.Id = id;

                collection._contracts.Add(contract);
            }

            collection.AllowResolution = true;

            foreach (var bindAction in bindActions)
            {
                bindAction();
            }

            return(collection);
        }
Exemple #2
0
        public void EnumContractTest()
        {
            EnumContract en = new EnumContract {
                BaseType = "short", TypeName = "StatusCode"
            };

            en.SetEnumItem("Success", 1010);
            en.SetEnumItem("Failed", -1);

            object val = en.GetEnumUnderlyingValue("Success");

            Debug.Assert(val.GetType().Equals(typeof(short)));
            Debug.Assert(val.Equals((short)1010), "枚举值定义不等于1010");

            //Console.WriteLine(EnumContract.DataEquals(1010, en["Success"].Value));
        }
        /// <summary>
        /// Get or create a read contract for <paramref name="type"/>.
        /// </summary>
        /// <param name="type">The type to get or create a read contract for.</param>
        /// <returns>The read contract corresponding to <paramref name="type"/>.</returns>
        public IReadContract GetOrAddReadContract(Type type)
        {
            if (type == typeof(Empty))
            {
                return(Intern(new EmptyContract()));
            }
            if (PrimitiveContract.CanProcess(type))
            {
                return(Intern(new PrimitiveContract(type)));
            }
            if (EnumContract.CanProcess(type))
            {
                return(Intern(new EnumContract(type)));
            }
            if (TupleReadContract.CanProcess(type))
            {
                return(Intern(new TupleReadContract(type, this)));
            }
            if (NullableReadContract.CanProcess(type))
            {
                return(Intern(new NullableReadContract(type, this)));
            }
            if (ListReadContract.CanProcess(type))
            {
                return(Intern(new ListReadContract(type, this)));
            }
            if (DictionaryReadContract.CanProcess(type))
            {
                return(Intern(new DictionaryReadContract(type, this)));
            }
            if (UnionReadContract.CanProcess(type))
            {
                return(Intern(new UnionReadContract(type, this)));
            }

            return(Intern(new ComplexReadContract(type, this)));
        }