分享
 
 
 

自定义Attribute

王朝学院·作者佚名  2016-05-20
窄屏简体版  字體: |||超大  

XsdGen:通过自定义Attribute与反射自动生成XSD前言 系统之间的数据交互往往需要事先定义一些契约,在WCF中我们需要先编写XSD文件,然后通过自动代码生成工具自动生成C#对象。对于刚刚接触契约的人来说,掌握xmlSpy之类的软件之后确实比手写XML效率要高,但还是有些学习成本的。此外XML的tag太多,如果设计的类型属性过多,手写XSD也不太现实,很难专注于设计。

于是我想能不能先用C#写好类型,然后自动生成标准格式的XSD呢。经过三天左右的设计和实现,目前实现了以下功能:

1. 支持Class和Enum类型的设计

2. 支持基元类型、自定义类型、泛型列表、自定义类型数组等属性

3. 支持自定义类型之间的依赖关系

4. 支持契约分组(指定Request/Response分到同一个xsd文件)

5. 支持契约汇总(对于自定义类型,最终体现在一个汇总xsd文件中,并自动引用其它xsd文件)

开源地址:https://github.com/CreateChen/XsdGen。我刚接触SOA不久,目前只添加了xsd的minOccurs、maxOccurs等基本属性,对于其它属性并没有全部集成进去,集成方式也非常简单,在Attribute中添加相应的属性,并在XsdBuilder.cs中添加相应的处理。

效果 先看一下实现的效果,例如我定义了以下类型:FoodOrderRequest、FoodOrderResponse、PayType

using System;using System.Collections.Generic;using XsdAttribute;[assembly: XsdSchema( TargetNamespace = "http://xx.com/framework/soa/sample/v1", XmlNamespace = "http://xx.com/framework/soa/sample/v1", Namespace = "http://xx.com/framework/soa/sample/v1", Common = "http://xx.com/common/types/v1")][assembly: XsdImport(Id = "SOACommonTypes", Namespace = "http://xx.com/common/types/v1", SchemaLocation = "SOACommonTypes_V1.0.0.xsd")]namespace TestDLL{ [XsdComplexType(Annotation = "订餐申请", FileGroup = "FoodOrder")] public class FoodOrderRequest { [XsdElement(MinOccurs = "1", Annotation = "餐馆编号")] public int RestaurantId { get; set; } [XsdElement(MinOccurs = "1", Annotation = "餐馆名称")] public string RestaurantName { get; set; } [XsdElement(Annotation = "订餐日期")] public DateTime OrderDate { get; set; } [XsdElement(MinOccurs = "0", MaxOccurs = "unbounded", Annotation = "食品编号")] public List<int> FoodId { get; set; } [XsdElement(MinOccurs = "1", Annotation = "业务类型")] public PayType BusinessType { get; set; } } [XsdComplexType(Annotation = "订餐结果", FileGroup = "FoodOrder")] public class FoodOrderResponse { [XsdElement(MinOccurs = "1", Annotation = "订单编号")] public int OrderId { get; set; } [XsdElement(Annotation = "预计送达时间")] public DateTime DeliveryTime { get; set; } } [XsdSimpleType(Annotation = "付款类型", FileGroup = "PayType")] public enum PayType { 现金, 支付宝, 微信, 网银 }}

工具自动为我生成了3个文件:

FoodOrder.xsd<?xml version="1.0" encoding="utf-8"?><xs:schema id="FoodOrder" targetNamespace="http://xx.com/framework/soa/sample/v1" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://xx.com/framework/soa/sample/v1" xmlns:ns="http://xx.com/framework/soa/sample/v1" xmlns:common="http://xx.com/common/types/v1"> <xs:include schemaLocation="PayType.xsd" /> <xs:import id="SOACommonTypes" schemaLocation="SOACommonTypes_V1.0.0.xsd" namespace="http://xx.com/common/types/v1" /> <xs:complexType name="FoodOrderRequestType"> <xs:annotation> <xs:documentation>订餐申请</xs:documentation> </xs:annotation> <xs:sequence> <xs:element name="RestaurantId" type="xs:int" minOccurs="1"> <xs:annotation> <xs:documentation>餐馆编号</xs:documentation> </xs:annotation> </xs:element> <xs:element name="RestaurantName" type="xs:string" minOccurs="1"> <xs:annotation> <xs:documentation>餐馆名称</xs:documentation> </xs:annotation> </xs:element> <xs:element name="OrderDate" type="xs:dateTime"> <xs:annotation> <xs:documentation>订餐日期</xs:documentation> </xs:annotation> </xs:element> <xs:element name="FoodId" type="xs:int" minOccurs="0" maxOccurs="unbounded"> <xs:annotation> <xs:documentation>食品编号</xs:documentation> </xs:annotation> </xs:element> <xs:element name="BusinessType" type="PayType" minOccurs="1"> <xs:annotation> <xs:documentation>业务类型</xs:documentation> </xs:annotation> </xs:element> </xs:sequence> </xs:complexType> <xs:complexType name="FoodOrderResponseType"> <xs:annotation> <xs:documentation>订餐结果</xs:documentation> </xs:annotation> <xs:sequence> <xs:element name="OrderId" type="xs:int" minOccurs="1"> <xs:annotation> <xs:documentation>订单编号</xs:documentation> </xs:annotation> </xs:element> <xs:element name="DeliveryTime" type="xs:dateTime"> <xs:annotation> <xs:documentation>预计送达时间</xs:documentation> </xs:annotation> </xs:element> </xs:sequence> </xs:complexType></xs:schema>

PayType.xsd<?xml version="1.0" encoding="utf-8"?><xs:schema id="PayType" targetNamespace="http://xx.com/framework/soa/sample/v1" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://xx.com/framework/soa/sample/v1" xmlns:ns="http://xx.com/framework/soa/sample/v1" xmlns:common="http://xx.com/common/types/v1"> <xs:import id="SOACommonTypes" schemaLocation="SOACommonTypes_V1.0.0.xsd" namespace="http://xx.com/common/types/v1" /> <xs:simpleType name="PayType" final="restriction"> <xs:restriction base="xs:string"> <xs:enumeration value="现金" /> <xs:enumeration value="支付宝" /> <xs:enumeration value="微信" /> <xs:enumeration value="网银" /> </xs:restriction> </xs:simpleType></xs:schema>

TestDLL.xsd<?xml version="1.0" encoding="utf-8"?><xs:schema id="TestDLL" targetNamespace="http://xx.com/framework/soa/sample/v1" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://xx.com/framework/soa/sample/v1" xmlns:ns="http://xx.com/framework/soa/sample/v1" xmlns:common="http://xx.com/common/types/v1"> <xs:import id="SOACommonTypes" schemaLocation="SOACommonTypes_V1.0.0.xsd" namespace="http://xx.com/common/types/v1" /> <xs:include schemaLocation="FoodOrder.xsd" /> <xs:include schemaLocation="PayType.xsd" /> <xs:element name="FoodOrderRequest" nillable="true" type="ns:FoodOrderRequestType" /> <xs:element name="FoodOrderResponse" nillable="true" type="ns:FoodOrderResponseType" /></xs:schema>

自定义Attribute1. Assembly的Attribute[AttributeUsage(AttributeTargets.Assembly)]public class XsdSchema : Attribute{ public string TargetNamespace { get; set; } public string XmlNamespace { get; set; } public string Namespace { get; set; } public string Common { get; set; } //汇总dll中的类型,生成总的xsd PRivate string _packageId; /// <summary> /// 生成XSD的文件名称 /// </summary> public string PackageId { get { return _packageId; } set { //去除文件名中非法字符 var regex = new Regex(@"\:|\;|\/|\\|\||\,|\*|\?|\""|\<|\>"); _packageId = regex.Replace(value, ""); } } public static XsdSchema Get(Assembly assembly) { return (XsdSchema) GetCustomAttribute(assembly, typeof (XsdSchema)); }}

前几个是一些命名空间的定义,可以根据自己公司的业务规则进行设计。默认情况下,汇总文件的targetId、文件名称以及生成的文件夹名称都是PackageId决定,如果dll没有指定该值,默认则是dll的Name。

除了定义Schema,每个xsd文件中可能还需要导入一些默认的公共类型,在这种情况下,可以为assembly添加如下Attribute:

[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]public class XsdImport : Attribute{ public string Id { get; set; } public string SchemaLocation { get; set; } public string Namespace { get; set; } public static IEnumerable<XsdImport> Get(Assembly assembly) { var attributes = GetCustomAttributes(assembly, typeof (XsdImport)); return attributes.Cast<XsdImport>(); }}

2. Class类型的Attribute[AttributeUsage((Attribut

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有