中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

Lind.DDD~實(shi)體屬性(xing)變(bian)更(geng)追蹤(zong)器的實(shi)現

回到目錄

看著這個標題很復雜,大叔把它拆開說一下,實體屬性-變更-追蹤器,把它拆成三部分大家看起來就容易懂一些了,實體屬性:領域實體里有自己的屬性,屬性有getter,setter塊,用來返回和設置屬性的內容;變更:當前屬性為賦值時,我們對它進行監視;追蹤器:對(dui)變量的(de)內容進行(xing)處理。好了(le)(le),我們(men)回到Lind.DDD框架中,在框架里有(you)領域(yu)實體(ti)(ti)基類(lei)EntityBase,這(zhe)個(ge)類(lei)是所(suo)有(you)實體(ti)(ti)的(de)基類(lei),它公開了(le)(le)一些屬性和方法,我們(men)對(dui)這(zhe)個(ge)基類(lei)進行(xing)一些設置,讓所(suo)有(you)子(zi)類(lei)都繼(ji)承(cheng)它,享用它。

1 屬(shu)性變更追蹤(zong)接(jie)口和它的事件

    // 摘(zhai)要:
    //     向客戶端(duan)發出某(mou)一(yi)屬性(xing)值已(yi)更改(gai)的通知。
    public interface INotifyPropertyChanged
    {
        // 摘要:
        //     在更改屬性值時發生。
        event PropertyChangedEventHandler PropertyChanged;
    }

2 基類EntityBase,添加了事件(jian)和它的方法,及觸發事件(jian)的方法

    /// <summary>
    /// 領域模(mo)型,實(shi)體模(mo)型基類(lei),它可(ke)能有多種持(chi)久化方(fang)式(shi),如DB,File,Redis,Mongodb,XML等
    /// Lind.DDD框架的領域(yu)模型與(yu)數(shu)據庫(ku)實體合二為一
    /// </summary>
    [PropertyChangedAttribute]
    public abstract class EntityBase : ContextBoundObject, IEntity, INotifyPropertyChanged
    {
        /// <summary>
        /// 實體初始(shi)化
        /// </summary>
        public EntityBase()
        {
            this.Status = Status.Normal;
            this.UpdateDateTime = DateTime.Now;
            this.CreateDateTime = DateTime.Now;
            this.PropertyChanged += EntityBase_PropertyChanged;
        }

        /// <summary>
        /// 建立時間
        /// </summary>
        [XmlIgnore, DataMember(Order = 3), XmlElement(Order = 3), DisplayName("建(jian)立時間(jian)"), Column("CreateTime"), Required]
        public DateTime CreateDateTime { get; set; }
        /// <summary>
        /// 更新時間
        /// </summary>
        [XmlIgnore, DataMember(Order = 2), XmlElement(Order = 2), DisplayName("更新時間"), Column("UpdateTime"), Required]
        public DateTime UpdateDateTime { get; set; }
        /// <summary>
        /// 實體狀態
        /// </summary>
        [XmlIgnore, DataMember(Order = 1), XmlElement(Order = 1), DisplayName("狀態"), Required]
        public Status Status { get; set; }

        /// <summary>
        /// 拿到(dao)實體驗(yan)證(zheng)的結(jie)果列表
        /// 結果為null或(huo)者Enumerable.Count()==0表達驗證成功
        /// </summary>
        /// <returns></returns>
        public IEnumerable<RuleViolation> GetRuleViolations()
        {
            var properties = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).ToArray();

            foreach (var i in properties)
            {
                var attr = i.GetCustomAttributes();
                foreach (var a in attr)
                {
                    var val = (a as ValidationAttribute);
                    if (val != null)
                        if (!val.IsValid(i.GetValue(this)))
                        {
                            yield return new RuleViolation(val.ErrorMessage, i.Name);
                        }
                }
            }

        }

        #region PropertyChangedEventHandler Events
        /// <summary>
        /// 屬性值變更(geng)事件(jian)
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// 事件實(shi)例
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void EntityBase_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            Console.WriteLine("屬性:{0},值:{1}", e.PropertyName, sender.GetType().GetProperty(e.PropertyName).GetValue(sender));
        }
        /// <summary>
        /// 觸發事件,寫在每個屬(shu)性(xing)(xing)的set塊中(zhong)CallerMemberName特性(xing)(xing)表示當前(qian)塊的屬(shu)性(xing)(xing)名(ming)
        /// </summary>
        /// <param name="propertyName"></param>
        public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

    }

3 定義變更攔(lan)截器特性

    /// <summary>
    /// 類中方法攔截的特性
    /// </summary>
    public class PropertyChangedAttribute : ProxyAttribute
    {
        public override MarshalByRefObject CreateInstance(Type serverType)
        {
            PropertyChangedProxy realProxy = new PropertyChangedProxy(serverType);
            return realProxy.GetTransparentProxy() as MarshalByRefObject;
        }
    }

4 實現攔截器功能

    /// <summary>
    /// 屬性(xing)變更(geng)攔截器
    /// </summary>
    public class PropertyChangedProxy : RealProxy
    {
        Type serverType;
        public PropertyChangedProxy(Type serverType)
            : base(serverType)
        {
            this.serverType = serverType;
        }
        public override IMessage Invoke(IMessage msg)
        {
            //構造方法(fa)
            if (msg is IConstructionCallMessage)
            {
                IConstructionCallMessage constructCallMsg = msg as IConstructionCallMessage;
                IConstructionReturnMessage constructionReturnMessage = this.InitializeServerObject((IConstructionCallMessage)msg);
                RealProxy.SetStubData(this, constructionReturnMessage.ReturnValue);
                return constructionReturnMessage;
            }
            //其它方法(fa)(屬性(xing)也是方法(fa),它會(hui)被翻譯成set_property,get_property,類(lei)似(si)于java里的屬性(xing)封(feng)裝(zhuang))
            else if (msg is IMethodCallMessage)
            {

                IMethodCallMessage callMsg = msg as IMethodCallMessage;
                object[] args = callMsg.Args;
                IMessage message;
                try
                {

                    if (callMsg.MethodName.StartsWith("set_") && args.Length == 1)
                    {
                        string propertyName = Regex.Split(callMsg.MethodName, "set_")[1];
                        //這里檢測到是set方法,然后應怎么調用對象(xiang)的其它(ta)方法呢(ni)?
                        var method = this.serverType.GetMethod("OnPropertyChanged");
                        if (method != null)
                        {
                            var obj = GetUnwrappedServer();
                            obj.GetType().GetProperty(propertyName).SetValue(obj, args.FirstOrDefault());
                            method.Invoke(obj, new object[] { propertyName });//這塊對象為空了(le)
                        }

                    }

                    object o = callMsg.MethodBase.Invoke(GetUnwrappedServer(), args);
                    message = new ReturnMessage(o, args, args.Length, callMsg.LogicalCallContext, callMsg);
                }

                catch (Exception e)
                {

                    message = new ReturnMessage(e, callMsg);

                }

                return message;

            }

            return msg;

        }
    }

5 總結

本(ben)例(li)子(zi)主要讓大(da)家了(le)解了(le)事件,事件觸發機(ji)制,AOP攔截技術(shu)等知識點,而且通(tong)過(guo)本(ben)例(li)子(zi),我們可以對(dui)類的屬性(xing)進行(xing)監視,并訂閱一些方法(fa)來處(chu)理這些變(bian)更行(xing)為!下(xia)面這個(ge)(ge)代碼是最(zui)簡單的屬性(xing)變(bian)更的記(ji)錄,本(ben)user對(dui)象為賦值時,它(ta)的兩(liang)個(ge)(ge)被set的屬性(xing)成(cheng)為了(le)監視的對(dui)象

     User u1 = new User();
     u1.UserName = "OK";
     u1.Age = 100;

回到目錄

 

posted @ 2015-12-07 14:19  張占嶺  閱讀(2379)  評論(0)    收藏  舉報