Implementation of lind.ddd~ entity property Change Tracker

Source: Internet
Author: User

Back to Catalog

Look at the title is very complicated, the uncle took it apart, the entity properties-change-tracker, split it into three parts you look easy to understand, entity properties: domain entities have their own attributes, attributes have Getter,setter block, used to return and set the content of the property; change: When the current property is assigned, we monitor it; Tracker : Handles the contents of a variable. Well, let's go back to the LIND.DDD framework, where there is the domain entity base class EntityBase, which is the base class for all entities, exposes properties and methods, and we set the base class to inherit it and enjoy it.

1 Property Change tracking interface and its events

    //  Summary:    //      notifies the client that a property value has changed. public    interface  inotifypropertychanged    {        //  Summary:         //      occurs when a property value is changed.         Event  propertychangedeventhandler propertychanged;    }

2 base class EntityBase, adds an event and its method, and the method that triggers the event

    /// <summary>    ///domain model, entity model base class, it may have multiple persistence methods, such as Db,file,redis,mongodb,xml, etc.///domain model of LIND.DDD framework merged with database entity/// </summary>[Propertychangedattribute] Public Abstract classEntitybase:contextboundobject, IEntity, inotifypropertychanged {/// <summary>        ///Entity Initialization/// </summary>         Publicentitybase () { This. Status =Status.normal;  This. Updatedatetime =DateTime.Now;  This. Createdatetime =DateTime.Now;  This. PropertyChanged + =entitybase_propertychanged; }        /// <summary>        ///Settling Time/// </summary>[XmlIgnore, DataMember (Order =3), XmlElement (Order =3), DisplayName ("Settling Time"), Column ("Createtime"), Required] PublicDateTime Createdatetime {Get;Set; } /// <summary>        ///Update Time/// </summary>[XmlIgnore, DataMember (Order =2), XmlElement (Order =2), DisplayName ("Update Time"), Column ("UpdateTime"), Required] PublicDateTime Updatedatetime {Get;Set; } /// <summary>        ///Entity Status/// </summary>[XmlIgnore, DataMember (Order =1), XmlElement (Order =1), DisplayName ("Status"), Required] PublicStatus Status {Get;Set; } /// <summary>        ///get the list of results for entity validation///result null or enumerable.count () ==0 expression validation succeeded/// </summary>        /// <returns></returns>         PublicIenumerable<ruleviolation>getruleviolations () {varProperties = This. GetType (). GetProperties (BindingFlags.Public |bindingflags.instance).            ToArray (); foreach(varIinchproperties) {                varattr =i.getcustomattributes (); foreach(varAinchattr) {                    varval = (A asValidationattribute); if(val! =NULL)                        if(!val. IsValid (I.getvalue ( This)))                        {                            yield return NewRuleviolation (val.                        ErrorMessage, I.name); }                }            }        }        #regionPropertyChangedEventHandler Events/// <summary>        ///Property Value Change Event/// </summary>         Public EventPropertyChangedEventHandler propertychanged; /// <summary>        ///Event Instances/// </summary>        /// <param name= "Sender" ></param>        /// <param name= "E" ></param>        voidEntitybase_propertychanged (Objectsender, PropertyChangedEventArgs e) {Console.WriteLine ("property: {0}, Value: {1}", E.propertyname, sender. GetType (). GetProperty (E.propertyname).        GetValue (sender)); }        /// <summary>        ///trigger event, written in the set block of each property Callermembername attribute represents the property name of the current block/// </summary>        /// <param name= "PropertyName" ></param>         Public voidOnPropertyChanged ([Callermembername]stringPropertyName =NULL)        {            if(PropertyChanged! =NULL) propertychanged ( This,NewPropertyChangedEventArgs (PropertyName)); }        #endregion    }

3 Defining the Change Interceptor feature

    /// <summary>    ///properties of method interception in class/// </summary>     Public classPropertychangedattribute:proxyattribute { Public OverrideMarshalByRefObject CreateInstance (Type servertype) {propertychangedproxy realProxy=NewPropertychangedproxy (ServerType); returnRealproxy.gettransparentproxy () asMarshalByRefObject; }    }

4 Implement Interceptor function

    /// <summary>    ///Property Change Blocker/// </summary>     Public classpropertychangedproxy:realproxy {Type servertype;  Publicpropertychangedproxy (Type servertype):Base(servertype) { This. ServerType =ServerType; }         Public OverrideIMessage Invoke (IMessage msg) {//Construction Method            if(msg isiconstructioncallmessage) {IConstructionCallMessage constructcallmsg= Msg asIConstructionCallMessage; IConstructionReturnMessage Constructionreturnmessage= This.                Initializeserverobject ((iconstructioncallmessage) msg); Realproxy.setstubdata ( This, Constructionreturnmessage.returnvalue); returnConstructionreturnmessage; }            //Other methods (attributes are also methods, which are translated into set_property,get_property, similar to the attribute encapsulation in Java)            Else if(msg isIMethodCallMessage) {IMethodCallMessage callmsg= Msg asIMethodCallMessage; Object[] args =Callmsg.args;                IMessage message; Try                {                    if(CallMsg.MethodName.StartsWith ("set_") && args. Length = =1)                    {                        stringPropertyName = Regex.Split (Callmsg.methodname,"set_")[1]; //The set method is detected here, and then how do I invoke the other methods of the object?                         varMETHOD = This. Servertype.getmethod ("onpropertychanged"); if(Method! =NULL)                        {                            varobj =Getunwrappedserver (); Obj. GetType (). GetProperty (PropertyName). SetValue (obj, args.                            FirstOrDefault ()); Method. Invoke (obj,New Object[] {propertyname});//this object is empty.                        }                    }                    Objecto =CallMsg.MethodBase.Invoke (Getunwrappedserver (), args); Message=Newreturnmessage (o, args, args.                Length, Callmsg.logicalcallcontext, callmsg); }                Catch(Exception e) {message=NewReturnMessage (E, callmsg); }                returnmessage; }            returnmsg; }    }

5 Summary

This example focuses on the event, event triggering mechanism, AOP interception technology and other knowledge points, and through this example, we can monitor the properties of the class and subscribe to some methods to handle the change behavior! The following code is the simplest record of property changes, and when this user object is assigned, its two set properties become the monitored object

     New User ();      " OK " ;      ;

Back to Catalog

Lind.ddd~ Entity Property Change Tracker Implementation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.