Application of attribute in. NET Programming (6)

Source: Internet
Author: User

. in the design of the Net Framework interception mechanism, there are a variety of message receivers between the client and the object. These message receivers form a linked list, and the client's call object process and call return implement interception, you can customize your own message receivers and insert them into the linked list to complete the pre-processing and post-processing of a call. So how is call interception structured or implemented?
in. net has two types of calls, one is cross-application domain, the other is cross-context, and the two types of calls both use the intermediate proxy ), proxy is divided into two parts: transparent proxy and actual proxy. The transparent proxy exposes the same public entry point as the object. When the client calls the transparent proxy, the transparent proxy converts the frames in the stack to messages (the object that implements the iMessage interface mentioned in the previous section ), the message contains the method name, parameters, and other attribute sets, and then transmits the message to the actual proxy. There are two cases: cross-application domain, the actual proxy uses a formatter to serialize the message and put it into a remote channel. In cross-context environments, the actual proxy does not need to know the formatter, channel, and context interceptor, it only needs to intercept the call before passing the message forward, and then it passes the message to a message receiver (the object implementing imessagesink). Each receiver knows its next receiver, after the messages are processed (pre-processed), the messages are transmitted to the next receiver until the last receiver of the linked list. The last receiver is called the stack generator, it restores the message to a stack frame and then calls the object. When the result of the call method is returned, the stack creator converts the result to a message and returns it to the message receiver that calls the method, so the message is passed back along the original linked list, The Message Receiver on each linked list processes the message before it returns the message. Until the first receiver of the linked list, the first receiver sends the message back to the actual proxy, the actual proxy passes the message to the transparent proxy, and the latter places the message back to the client stack. From the above description, we can see that the message traversing the context does not need to be formatted. CLR uses an internal channel called crosscontextchannel. This object is also a message receiver.

There are several types of message receivers. One call can be intercepted on the server or on the client. The server receiver intercepts all calls to objects in the server context, both pre-processing and post-processing are performed. The client receiver intercepts all calls from the context environment of the client, and also performs some pre-processing and post-processing. The server is responsible for the installation of the server receiver. the receiver that intercepts access to the server context is called the server context receiver. the receiver that intercepts calling the actual object is the object receiver. The client receiver installed by the customer is called the client context receiver, and the client receiver installed by the object is called the Special Envoy (envoy) receiver, which intercepts only those objects associated with it. The last receiver of the client and the first receiver of the server are instances of the crosscontextchannel type. Different types of receivers form different segments. Each segment endpoint is installed with a receiver called The Terminator. The Terminator transmits messages in this segment to the next segment. The last terminator in the server context section is servercontextterminatorsink. If you call nextsink In the Terminator, it will return a null value, which acts like a dead end header, but stores private fields of the next receiver object inside them.

We roughly introduced the implementation mechanism of object call interception in. NET Framework. The purpose is to give everyone an understanding of this mechanism. Now we are implementing it.CodeYou can see how messages are processed through code implementation. First, for usProgramDefine a receiver calltracesink:

// Tracecontext. CS

Using system;
Using system. runtime. remoting. contexts;
Using system. runtime. remoting. messaging;
Using system. runtime. remoting. activation;

Namespace niwalkerdemo
{
Public class calltracesink: imessagesink // implement imessagesink
{
Private imessagesink nextsink; // save the next receiver

// Initialize the next receiver in the constructor
Public calltracesink (imessagesink next)
{
Nextsink = next;
}

// Required imessagesink interface attributes
Public imessagesink nextsink
{
Get
{
Return nextsink;
}
}

// Implement the imessagesink interface method. This method is called when a message is sent.
Public iMessage syncprocessmessage (iMessage MSG)
{
// Intercept messages for pre-processing
Preprocess (MSG );
// Send the message to the next receiver
IMessage retmsg = nextsink. syncprocessmessage (MSG );
// Intercept and post-process the response
Postprocess (MSG, retmsg );
Return retmsg;
}

// Imessagesink interface method, which is used for asynchronous processing. We do not implement asynchronous processing, so null is returned simply,
// Whether synchronous or asynchronous, this method must be defined
Public imessagectrl asyncprocessmessage (iMessage MSG, imessagesink replysink)
{
Return NULL;
}

// Our pre-processing method is used to check the inventory. For the sake of simplification, we have written the inventory check and emails together,
// In actual implementation, you may also need to bind the inventory object to a context,
// In addition, you can design the email sending as another receiver and install it through nextsink.
Private void preprocess (iMessage MSG)
{
// Check whether it is a method call. We only block the submit method of order.
Imethodcallmessage call = MSG as imethodcallmessage;

If (call = NULL)
Return;

If (call. methodname = "Submit ")
{
String Product = call. getarg (0). tostring (); // obtain the first parameter of the submit method.
Int qty = (INT) Call. getarg (1); // obtain the second parameter of the submit Method

// Call inventory to check inventory
If (new inventory (). Checkout (product, qty ))
Console. writeline ("Order availible ");
Else
{
Console. writeline ("Order unvailible ");
Sendemail ();
}
}
}

// Post-processing method, used to record order submission information, and can also use the record as a receiver
// We will handle it here only for demonstration
Private void postprocess (iMessage MSG, iMessage retmsg)
{
Imethodcallmessage call = MSG as imethodcallmessage;

If (call = NULL)
Return;
Console. writeline ("log order information ");
}

Private void sendemail ()
{
Console. writeline ("send email to Manager ");
}
}
...
Next, we will define the attributes of the context environment. The context attributes must implement corresponding interfaces based on the type of the receiver you want to create. For example, if you create a server context receiver, you must implement the icontributeservercontextsink interface.
...
Public class calltraceproperty: icontextproperty, icontributeobjectsink
{
Public calltraceproperty ()
{
}

// Icontributeobjectsink interface method, instantiate the Message Receiver
Public imessagesink getobjectsink (export albyrefobject OBJ, imessagesink next)
{
Return new calltracesink (next );
}

// Icontextproperty interface method. If this method returns true, the object is activated in the new context.
Public bool isnewcontextok (context newctx)
{
Return true;
}

// Icontextproperty Interface Method for advanced use
Public void freeze (context newctx)
{
}

// Icontextproperty interface Property
Public string name
{
Get {return "ordertrace ";}
}
}
...
Contextattribute
...
[Attributeusage (attributetargets. Class)]
Public class calltraceattribute: contextattribute
{
Public calltraceattribute (): Base ("calltrace ")
{
}

// Reload the contextattribute method to create a context attribute
Public override void getpropertiesfornewcontext (iconstructioncallmessage ctormsg)
{
Ctormsg. contextproperties. Add (New calltraceproperty ());
}
}
}
To see how the submit method of the Order object is blocked, we will slightly modify the order class and design it as a contextboundobject derived class:
// Inventory. CS

// Order. CS
Using system;

namespace niwalkerdemo
{< br> [calltrace]
public class order: contextboundobject
{< br>...
Public void submit (string product, int quantity)
{< br> This. product = product;
This. quantity = quantity;
}< br>...
}< BR >}

Client call code:
...
Public class appmain
{
Static void main ()
{
Order Order1 = New Order (100 );
Order1.submit ("Item1", 150 );

Order order2 = New Order (101 );
Order2.submit ("item2", 150 );
}
}
...
The running result indicates that we successfully intercepted order's sbumit. It should be noted that the Code here is only used as a demonstration of the contextattribute application, and it is crude. In practice, you can design more precisely.

Note: I wanted to introduce attribute more and found that there are too many things to talk about. Allow me to discuss them in other topics. Thank you for your patience in reading this series. It would be a great honor for me if the content I introduced here has inspired you in your programming career. Thank you again. (Full text)

 

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.