国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

使用AOP改進(jìn)Fireasy實(shí)體模型

2019-11-17 02:27:52
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

使用AOP改進(jìn)Fireasy實(shí)體模型

目前Fireasy中的實(shí)體模型雖然用CodeBuilder生成,但是還是比較龐大,手工維護(hù)起來(lái)比較吃力,因此一直想使用比較簡(jiǎn)單的一種模型,比如屬性只有 get 和 set,最多加個(gè)ColumnAttribute之類的來(lái)做映射。但這樣做的話,屬性修改這一特性就無(wú)法保持了,即更新實(shí)體時(shí)不知道哪些屬性有改動(dòng)過(guò)。

我們先看一下目前生成的實(shí)體類代碼:

    /// <summary>    /// 部門 實(shí)體類。    /// </summary>    [Serializable]    [EntityMapping("TB_DEPT", Description = "部門")]    public partial class Dept : EntityObject    {        #region Static PRoperty Definition                /// <summary>        /// ID的依賴屬性。        /// </summary>        public static readonly IProperty EpId = PropertyUnity.RegisterProperty<Dept>(s => s.Id, new PropertyMapInfo { IsPrimaryKey = true, IsNullable = false, Length = 36, Description = "ID", FieldName = "ID" });        /// <summary>        /// 編碼的依賴屬性。        /// </summary>        public static readonly IProperty EpNo = PropertyUnity.RegisterProperty<Dept>(s => s.No, new PropertyMapInfo { Length = 50, Description = "編碼", FieldName = "NO" });        /// <summary>        /// 名稱的依賴屬性。        /// </summary>        public static readonly IProperty EpName = PropertyUnity.RegisterProperty<Dept>(s => s.Name, new PropertyMapInfo { Length = 50, Description = "名稱", FieldName = "NAME" });        /// <summary>        /// 排序的依賴屬性。        /// </summary>        public static readonly IProperty EpOrderNo = PropertyUnity.RegisterProperty<Dept>(s => s.OrderNo, new PropertyMapInfo { Description = "排序", FieldName = "ORDER_NO" });        #endregion        #region Properties                /// <summary>        /// 獲取或設(shè)置ID。        /// </summary>        public string Id        {            get { return (string)GetValue(EpId); }            set { SetValue(EpId, value); }        }        /// <summary>        /// 獲取或設(shè)置編碼。        /// </summary>        public string No        {            get { return (string)GetValue(EpNo); }            set { SetValue(EpNo, value); }        }        /// <summary>        /// 獲取或設(shè)置名稱。        /// </summary>        public string Name        {            get { return (string)GetValue(EpName); }            set { SetValue(EpName, value); }        }        /// <summary>        /// 獲取或設(shè)置排序。        /// </summary>        public int? OrderNo        {            get { return (int?)GetValue(EpOrderNo); }            set { SetValue(EpOrderNo, value); }        }        #endregion    }

以上的實(shí)體模型,主要借鑒WPF中的依賴屬性原理,定義一個(gè)靜態(tài)的Field實(shí)現(xiàn)關(guān)系映射,最主要的一點(diǎn),就是在設(shè)置屬性的時(shí)候,交由基類的SetValue方法來(lái)執(zhí)行,它會(huì)把這個(gè)修改過(guò)的屬性記下來(lái),在更新實(shí)體的時(shí)候,達(dá)到只更新修改過(guò)的屬性的目的。

而GetValue和SetValue看似有裝箱和拆箱操作,實(shí)際上屬性的值是以PropertyValue這個(gè)結(jié)構(gòu)存儲(chǔ)的,通過(guò)重載強(qiáng)制轉(zhuǎn)換和顯式轉(zhuǎn)換操作符來(lái)交換數(shù)據(jù),所以這里不用擔(dān)心啦。

那么,實(shí)際上有了EntityObject基類就好辦多了,可以再抽象出一個(gè)類,讓它基于AOP來(lái)創(chuàng)建,在設(shè)置屬性值之后和獲取屬性值之后分別調(diào)用SetValue和GetValue就好了。

Fireasy本來(lái)就提供了AOP,在Fireasy.Common.Aop命名空間中,關(guān)鍵是IInterceptor這個(gè)接口,它通過(guò)InterceptAttribute特性來(lái)綁定要攔截的方法、屬性或是整個(gè)類。

還有一個(gè)接口IAopSupport,它只起到一個(gè)標(biāo)識(shí),在擴(kuò)展方法New中,如果類型實(shí)現(xiàn)了IAopSupport,那么則使用aspectFactory來(lái)創(chuàng)建對(duì)象。

好,接下來(lái)我們定義一個(gè)LighEntityObject 類:

    [Intercept(typeof(LighEntityInterceptor))]    public abstract class LighEntityObject<TEntity> : EntityObject,         IAopSupport,         IEntityPropertyInitialize        where TEntity : IEntity    {        /// <summary>        /// 構(gòu)造一個(gè)代理對(duì)象。        /// </summary>        /// <returns></returns>        public static TEntity New()        {            return typeof(TEntity).New<TEntity>();        }        void IEntityPropertyInitialize.Initialize()        {            var entityType = this.GetType();            foreach (var property in entityType.BaseType.GetProperties(BindingFlags.Public | BindingFlags.Instance))            {                if (property.DeclaringType == entityType.BaseType)                {                    //定義為 virtual                    var getMth = property.GetGetMethod();                    if (getMth != null && getMth.IsVirtual && !getMth.IsFinal)                    {                        RegisterProperty(entityType.BaseType, property);                    }                }            }        }        private void RegisterProperty(Type entityType, PropertyInfo property)        {            //關(guān)聯(lián)屬性,即關(guān)聯(lián)實(shí)體或子實(shí)體集屬性            if (typeof(IEntity).IsAssignableFrom(property.PropertyType) ||                typeof(IEntitySet).IsAssignableFrom(property.PropertyType))            {                var mapping = property.GetCustomAttributes<PropertyMappingAttribute>().FirstOrDefault();                var options = mapping != null && mapping.GetFlag(PropertyMappingAttribute.SetMark.LoadBehavior) ?                    new RelationOptions(mapping.LoadBehavior) : null;                PropertyUnity.RegisterSupposedProperty(property.Name, property.PropertyType, entityType, options: options);            }            else            {                var gp = new GeneralProperty()                    {                        Name = property.Name,                        Type = property.PropertyType,                        EntityType = entityType,                        Info = new PropertyMapInfo { ReflectionInfo = property, FieldName = property.Name }                    };                var mapping = property.GetCustomAttributes<PropertyMappingAttribute>().FirstOrDefault();                if (mapping != null)                {                    InitMapInfo(mapping, gp.Info);                }                PropertyUnity.RegisterProperty(entityType, gp);            }        }        /// <summary>        /// 根據(jù)映射特性設(shè)置屬性的映射信息。        /// </summary>        /// <param name="mapping"></param>        /// <param name="mapInfo"></param>        private void InitMapInfo(PropertyMappingAttribute mapping, PropertyMapInfo mapInfo)        {            mapInfo.FieldName = mapping.ColumnName;            mapInfo.Description = mapping.Description;            mapInfo.GenerateType = mapping.GenerateType;            if (mapping.GetFlag(PropertyMappingAttribute.SetMark.DataType))            {                mapInfo.DataType = mapping.DataType;            }            if (mapping.GetFlag(PropertyMappingAttribute.SetMark.IsPrimaryKey))            {                mapInfo.IsPrimaryKey = mapping.IsPrimaryKey;            }            if (mapping.GetFlag(PropertyMappingAttribute.SetMark.IsDeletedKey))            {                mapInfo.IsDeletedKey = mapping.IsDeletedKey;            }            if (mapping.DefaultValue != null)            {                mapInfo.DefaultValue = PropertyValue.New(mapping.DefaultValue, mapInfo.ReflectionInfo.PropertyType);            }            if (mapping.GetFlag(PropertyMappingAttribute.SetMark.Length))            {                mapInfo.Length = mapping.Length;            }            if (mapping.GetFlag(PropertyMappingAttribute.SetMark.Precision))            {                mapInfo.Precision = mapping.Precision;            }            if (mapping.GetFlag(PropertyMappingAttribute.SetMark.Scale))            {                mapInfo.Scale = mapping.Scale;            }        }    }

關(guān)鍵還是攔截器了,看下面代碼:

    public sealed class LighEntityInterceptor : IInterceptor    {        void IInterceptor.Initialize(InterceptContext context)        {        }        void IInterceptor.Intercept(InterceptCallInfo info)        {            if (info.InterceptType == InterceptType.AfterGetValue ||                info.InterceptType == InterceptType.AfterSetValue)            {                var entity = info.Target as EntityObject;                var entityType = entity.EntityType;                var property = PropertyUnity.GetProperty(entityType, info.Member.Name);                if (property == null)                {                    return;                }                switch (info.InterceptType)                {                    case InterceptType.AfterGetValue:                        var value = entity.GetValue(property);                        if (value != null && !value.IsEmpty)                        {                            info.ReturnValue = value.GetStorageValue();                        }
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 大庆市| 玉屏| 阳新县| 五华县| 新邵县| 钟山县| 扎赉特旗| 新昌县| 娱乐| 保山市| 湘乡市| 德兴市| 江油市| 大厂| 枣庄市| 福州市| 白水县| 乾安县| 吉首市| 加查县| 东兴市| 哈尔滨市| 临澧县| 耒阳市| 绵竹市| 高唐县| 长垣县| 西充县| 拜城县| 陇川县| 龙胜| 临高县| 民丰县| 淄博市| 岳西县| 砚山县| 牟定县| 三穗县| 枞阳县| 普陀区| 长丰县|