fastCSharp代码生成的底层应用框架

联合创作 · 2023-10-01 00:32


fastCSharp是一个基于.NET元数据的代码生成底层应用框架,目标是打造一个“开发+运行效率双优的开源框架。


经过半年多的时间,除了与web开发直接相关的部分,都已经在fastCSharp part 1.5中完成了重写工作。


fastCSharp现在实现的代码生成实例主要有5个


1、基于缓存查询模式的ORM代码生成实例(现在只支持MSSQL),自定义配置类是fastCSharp.setup.cSharp.sqlTable,同时支持反射模式fastCSharp.setup.cSharp.sqlTable.sqlTool。


下面是ORM的model定义示例













1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33


34


35


36


37


38


39


40


41


42


43


44


45


46


47


48


49



    [fastCSharp.setup.cSharp.sqlTable(ConnectionName = "Connection1")]


    public partial class model1


    {


        /// 


        /// 自增列,一个表格只允许一个,如果不配置IsIdentity = true,将自动匹配名称为 id 的成员


        /// 


        [fastCSharp.setup.sqlMember(IsIdentity = true)]


        public int id;


 


        /// 


        /// 关键字1,多个关键字成员按照成员定义顺序一致


        /// 


        [fastCSharp.setup.sqlMember(IsPrimaryKey = true)]


        public int key1;


        /// 


        /// 关键字2


        /// 


        [fastCSharp.setup.sqlMember(IsPrimaryKey = true, IsAscii = true, MaxLength = 32)]


 


        public string key2;


        public enum EnumByte : byte


        {


             Enum1


        }


        /// 


        /// 直接支持枚举类型转换,可以不指定SqlType = typeof(byte)


        /// 


        [fastCSharp.setup.sqlMember(SqlType = typeof(byte))]


        public EnumByte key2;


 


        /// 


        /// 指定隐式类型转换


        /// 


        [fastCSharp.setup.sqlMember(SqlType = typeof(string))]


        public partial struct image


        {


            public string url;


            /// 


            /// 如果不能隐式类型转换,必须实现互转函数


            /// 


            public static implicit operator image(string url) { return new image { url = url }; }


            public static implicit operator string(image image) { return image.url; }


        }


        /// 


        /// 支持隐式类型转换


        /// 


        [fastCSharp.setup.sqlMember(IsAscii = true, MaxLength = 64)]


        public image icon = string.Empty;


    }



 fastCSharp的配置文件是一个纯数据的json格式文件,比如 Connection1 的配置定义













1


2


3


4


5


6


7


8


9


10


11


12



{


sql:    {


    checkConnection:["Connection1"],


    Connection1:


        {


        Diantou:{


            Type:"sql2008",


            Connection:"server=192.168.0.100;database=dbname;uid=username;pwd=password"


            }


        }


    }


}



 下面是代码生成模式示例,采用派生类的模式













1


2


3


4


5


6


7


8


9


10


11


12


13


14



    public partial class bModel1 : model1.sqlTable


    {


        static bModel1()


        {


            if (SqlTool != null)


            {


                //定义缓存


                Cache = new fastCSharp.sql.cache.whole.identityArray(SqlTool);


                //定义缓存同步个性化处理事件


                Cache.OnInserted += XXX;


                Cache.OnUpdated += XXX;


            }


        }


    }



 有时候多个表格结构相同,那么只需要定义一个model,比如可以













1


2


3


4


5


6


7


8


9


10



    public abstract class bModelBase : model1.sqlTable


        where tableType : bModelBase


    {


    }


    public partial class bModel1_1 : bModelBase


    {


    }


    public partial class bModel1_N : bModelBase


    {


    }



 下面是反射模式示例













1


2


3


4


5


6


7


8


9


10


11



    public class bModel1 : model1


    {


        private static readonly fastCSharp.setup.cSharp.sqlTable.sqlTool sqlTool = fastCSharp.setup.cSharp.sqlTable.sqlTool.Default;


        static bModel1()


        {


            if (sqlTool != null)


            {


                //缓存定义与事件定义 和 代码生成模式示例一样


            }


        }   


    }



 有人说ORM不适应于复杂的综合查询。真的吗?我现在展示一段查询代码













1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16



                return diantou.dataProxy.questionTopic.getTopicCache(id)


                    .getArray(value => diantou.dataProxy.question.get(value.linkId))


                    .getHash(value => value.bestAnswerId)


                    .getArray(value => diantou.dataProxy.answer.get(value))


                    .getFind(value => value != null)


                    .group(value => value.userId)


                    .getArray(value => new keyValue(diantou.dataProxy.user.get(value.Key), value.Value.Count))


                    .group(value => value.Key.grade0)


                    .getArray(value => new userStat


                    {


                        grade0 = value.Key,


                        count = value.Value.Count,


                        path = topic.path.bestAnswer,


                        users = value.Value.rangeSort((left, right) => right.Value - left.Value, 0, 6)


                            .getArray(user => diantou.dataProxy.user.get(user.Key, userId))


                    });



 这个查询需求是,先根据话题(topic)ID查找相关联的问题(question)ID集合,然后找到这些问题的最佳答案(answer)ID集合,然后根据这些答案的用户(user)ID分组统计答案数量,最后将这些用户根据用户等级分组,每个分组根据答案数量取前6个用户。


我个人认为基于ORM的查询更简单流畅。如果用SQL实现这个需求,该是一个多么复杂的SQL语句?如果需求有一点点变化,修改这个SQL语句该是多麻烦的事?


2、数据类快速序列化代码生成实例,自定义配置类是fastCSharp.setup.cSharp.serialize,同时支持反射模式













1


2


3


4


5


6


7



    /// 


    /// 仅仅选择字段成员,反射模式可以不必配置


    /// 


    [fastCSharp.setup.cSharp.serialize(Filter = fastCSharp.setup.memberFilter.InstanceField)]


    public partial class model1


    {


    }



 代码生成模式将实现接口fastCSharp.setup.cSharp.serialize.ISerialize













1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33


34


35


36


37


38



        /// 


        /// 序列化接口


        /// 


        public interface ISerialize


        {


            /// 


            /// 对象序列化


            /// 


            /// 序列化数据


            byte[] Serialize();


            /// 


            /// 对象序列化


            /// 


            ///  数据流


            void Serialize(memoryStream stream);


            /// 


            /// 对象序列化


            /// 


            ///  对象序列化器


            void Serialize(dataSerializer serializer);


            /// 


            /// 反序列化


            /// 


            ///  序列化数据


            bool DeSerialize(byte[] data);


            /// 


            /// 反序列化


            /// 


            ///  序列化数据


            /// 起始位置


            /// 结束位置


            bool DeSerialize(byte[] data, int startIndex, out int endIndex);


            /// 


            /// 反序列化


            /// 


            /// 对象反序列化器


            void DeSerialize(deSerializer deSerializer);


        }



 如果自定义配置IsStreamSerialize = true,将实现接口fastCSharp.setup.cSharp.serialize.IStreamSerialize













1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16



        /// 


        /// 序列化流接口


        /// 


        public interface IStreamSerialize : ISerialize


        {


            /// 


            /// 对象序列化


            /// 


            /// 数据流


            void Serialize(Stream stream);


            /// 


            /// 对象序列化


            /// 


            /// 对象序列化器


            void Serialize(streamSerializer serializer);


        }



 反射模式的话,直接调用反射函数













1


2


3



fastCSharp.setup.cSharp.serialize.dataSerialize.Get(value);


fastCSharp.setup.cSharp.serialize.streamSerialize.Get(value);


fastCSharp.setup.cSharp.serialize.deSerialize.Get(data);



 


3、TCP(静态方法)调用代码生成实例,自定义配置类是fastCSharp.setup.cSharp.tcpCall,支持泛型支持跨类(只能支持单例),不支持反射模式。下面是示例:













1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33


34


35


36



    /// 


    /// 序列化流接口


    /// 


    [fastCSharp.setup.cSharp.tcpCall(Service = "tcpCallVerifyAsynchronous", VerifyType = typeof(tcpVerifyAsynchronous))]


    public partial class tcpCallVerifyAsynchronous


    {


        [fastCSharp.setup.cSharp.tcpCall(IsClientAsynchronous = false)]


        protected static void action()


        {


            isServer = true;


        }


        [fastCSharp.setup.cSharp.tcpCall(IsClientAsynchronous = true)]


        protected static void actionAsynchronous()


        {


            isServer = true;


        }


        [fastCSharp.setup.testCase]


        internal static bool Test()


        {


            using (fastCSharp.testCase.tcpServer.tcpCallVerifyAsynchronous server = new fastCSharp.testCase.tcpServer.tcpCallVerifyAsynchronous())


            {


                if (!server.Start()) throw new Exception("tcpCallVerifyAsynchronous");


                if (fastCSharp.testCase.tcpClient.tcpCallVerifyAsynchronous.defaultTcpServer.IsServer) throw new Exception("IsServer");


 


                isServer = false;


                tcpCall.tcpCallVerifyAsynchronous.action();


                checkServer("action");


 


                isServer = false;


                isReturn = null;


                tcpCall.tcpCallVerifyAsynchronous.actionAsynchronous(actionAsynchronousReturn);


                checkIsReturn("actionAsynchronous");


            }


            return true;


        }


    }



 


4、TCP(动态方法)服务代码生成实例,自定义配置类是fastCSharp.setup.cSharp.tcpServer,支持泛型不支持跨类不支持反射模式。下面是示例:













1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33


34



    [fastCSharp.setup.cSharp.tcpServer(Service = "tcpServerVerifyAsynchronous", VerifyType = typeof(tcpVerifyAsynchronous))]


    public partial class tcpServerVerifyAsynchronous


    {


        [fastCSharp.setup.cSharp.tcpServer(IsClientAsynchronous = false)]


        protected void action()


        {


            isServer = true;


        }


        [fastCSharp.setup.cSharp.tcpServer(IsClientAsynchronous = true)]


        protected void actionAsynchronous()


        {


            isServer = true;


        }


        [fastCSharp.setup.testCase]


        internal static bool Test()


        {


            using (fastCSharp.testCase.tcpServer.tcpServerVerifyAsynchronous server = new fastCSharp.testCase.tcpServer.tcpServerVerifyAsynchronous())


            {


                if (!server.Start()) throw new Exception("tcpServerVerifyAsynchronous");


                using (fastCSharp.testCase.tcpClient.tcpServerVerifyAsynchronous client = new fastCSharp.testCase.tcpClient.tcpServerVerifyAsynchronous())


                {


                    isServer = false;


                    client.action();


                    checkServer("action");


 


                    isServer = false;


                    isReturn = null;


                    client.actionAsynchronous(actionAsynchronousReturn);


                    checkIsReturn("actionAsynchronous");


                }


            }


            return true;


        }


    }



与TCP(静态方法)调用代码生成实例相似,可以参考一下fastCSharp.setup.tcpRegister。


5、快速json处理代码生成实例,自定义配置类是fastCSharp.setup.cSharp.ajax,同时支持反射模式












1


2


3


4


5


6


7



    /// 


    /// 可以选择只生成 序列化 或者 反序列化 的代码,反射模式可以不必配置


    /// 


    [fastCSharp.setup.cSharp.ajax(IsToJson = true, IsParseJson = true)]


    public partial class model1


    {


    }





代码生成模式将实现接口fastCSharp.setup.cSharp.ajax.IToJson与fastCSharp.setup.cSharp.ajax.IParseJson












1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32



        /// 


        /// 对象转换成JSON字符串接口


        /// 


        public interface IToJson


        {


            /// 


            /// 对象转换成JSON字符串


            /// 


            /// JSON字符串


            string ToJson();


            /// 


            /// 对象转换成JSON字符串


            /// 


            /// 对象转换JSON字符串


            void ToJson(toJsoner toJsoner);


        }


        /// 


        /// JSON字符串转换成对象接口


        /// 


        public interface IParseJson


        {


            /// 


            /// JSON字符串转换成对象


            /// 


            /// JSON字符串


            void FromJson(string json);


            /// 


            /// JSON字符串解析节点换成对象


            /// 


            /// JSON字符串解析节点


            void FromJson(jsonNode node);


        }





反射模式的话,直接调用反射函数













1


2



fastCSharp.setup.cSharp.ajax.toJson.Get(value);


fastCSharp.setup.cSharp.ajax.parseJson.Get(json);



 


由于很多人不需要代码生成那么好的运行效率,也不想配置初始环境,所以某些代码生成实例提供了基于反射的实例实现。有的代码生成实例需要生成代理实例(比如TCP调用),没有办法使用反射实现相同的效果。


今天是我在现在这个公司工作的最后一天了,感谢李陶冶大牛这几年对我的照顾,感谢你对于这个项目开源发展的支持。也许过几天我就回老家“休息”了,在这里默默的祝福你和51nod能够一切顺利。


最后欢迎对算法有兴趣的朋友到基于fastCSharp开发的51nod OJ上去AC问题或者讨论算法问题。
浏览 22
点赞
评论
收藏
分享

手机扫一扫分享

编辑 分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

编辑 分享
举报