Self-implemented simple AOP (1) Introduction to Implementing aop

Source: Internet
Author: User

Self-implemented simple AOP (1) Introduction to Implementing aop

AOP and OOP are two complementary technologies in my opinion. As a supplement to OOP, AOP has its own special application scenarios.

Suppose we need to implement the following basic functions at the Service layer:

/// <Para> 1. Automatically manage database connections [Optional] </para>
/// <Para> 2. Automatically manages database transactions. When an exception is received (no matter what exception), the transaction is automatically rolled back. [Optional] </para>
/// <Para> 3. Service-Level Lock [required] </para>
/// <Para> 4. Handle service exceptions and errors in a unified manner, including database exceptions and exceptions actively thrown [required] </para>

Explanation:
1. Open the database connection before executing the Service method, and close the database connection after executing the Service method.
2. Begin database transaction before executing the Service method, Commit database transaction after executing the Service method, and RollBack database transaction after Catch exception

3. lock the entire Service method and lock the private static objects of the Service to ensure thread security and synchronization of Service-level methods.
4. Capture all uncaptured exceptions in the Service method. After an exception is caught, if you need to automatically close the connection and roll back the transaction. And records the exception information.
That is, when an error is actively reported, you only need to throw an exception.

 

In order to implement the above functions, it is easy to implement and does not break the existing C # encoding specifications.
Therefore, introduce AOP and use Attribute to specify the enhancement object for the method,
To enhance the execution method (including opening a connection and opening a transaction) before calling the Service method)
After the Service method is called, the post-Enhancement of the execution method (including closing the connection and committing transactions)
And implement Try... Catch exception capture and Lock for the entire call method.

 

C # introduces the concept of Proxy, that is, System. Runtime. Remoting. Proxies. RealProxy provides the basic functions of Proxy. You can use this object to implement AOP programming by yourself.

RealProxy can be used to provide proxy for any "directly or indirectly inherited from System. externalbyrefobject" type.
RealProxy can create a proxy object for a specified type. The type of the created proxy object can be seen as a subclass of the specified type (but the specified type can be a SEAL class ).
[PS: As a subclass, it is easier to understand. Essentially, the type of the created proxy object and the specified type are directly in a combination, rather than an inheritance relationship]


How RealProxy works:
Hypothesis:
T is the type to be proxy, t is the object
ProxyT is the created proxy type, and proxyT is the object

The member method Test () exists in the T type ();
ProxyT inherits from T [in fact, it is not an inheritance relationship, it should be a combination, to facilitate understanding as an inheritance relationship], ProxyT also has the method Test


When the following code is executed:
ProxyT. Test ();

. NET runtime automatically calls the System. Runtime. Remoting. Proxies. RealProxy. Invoke (...) method.
This method is an abstract method. You can rewrite this method and call t. Test () in the method ().
Before the call, execute the pre-enhancement; after the call, execute the post-enhancement; and other processing operations.
This allows you to implement AOP programming and improve weaving.

 

Custom RealProxy

Using System; using System. collections. generic; using System. linq; using System. web; using System. runtime. remoting. messaging; using System. runtime. remoting. proxies; namespace AOPDemo. common {public class DelayProxy <T>: RealProxy {private static object objLock = new object (); /// <summary> /// proxy object // </summary> private T target; public DelayProxy (T target): base (typeof (T )) {this.tar get = target;} public override IMessage Invoke (IMessage msg) {IMethodCallMessage callMessage = (IMethodCallMessage) msg; Console. writeLine ("before the method is called"); Console. writeLine ("Call method name:" + callMessage. methodName); IMessage message = DelayProxyUtil.InvokeBeProxy(this.tar get, callMessage); Console. writeLine ("after the method is called"); return message ;}}}RealProxy

Auxiliary Tools

Using System; using System. collections. generic; using System. linq; using System. web; using System. runtime. remoting. proxies; using System. runtime. remoting. messaging; using System. reflection; namespace AOPDemo. common {// <summary> /// delay initialization proxy tool class // </summary> public static class DelayProxyUtil {// <summary> // call the proxy object method, return the method return value of the proxy object // <para> supports the out ref parameter </para> /// </summary> /// <param name = "target"> </param> /// <param name = "callMessage"> </param> /// <returns> </returns> public static IMessage InvokeBeProxy (object target, IMethodCallMessage callMessage) {var args = callMessage. args; object returnValue = callMessage. methodBase. invoke (target, args); return new ReturnMessage (returnValue, args, args. length, callMessage. logicalCallContext, callMessage );} /// <summary> /// throw an exception to the upper layer /// </summary> /// <param name = "ex"> </param> /// <param name = "callMessage"> </param> // <returns> </returns> public static IMessage ReturnExecption (Exception ex, IMethodCallMessage callMessage) {return new ReturnMessage (ex, callMessage );} /// <summary> /// get the proxy of the object /// </summary> /// <param name = "type"> </param> /// <param name = "instance"> </param> // <param name = "delay"> </param> // <returns> </returns> public static object GetTransparentProxy (type type, object instance) {Type tmpType = typeof (DelayProxy <>); tmpType = tmpType. makeGenericType (type); RealProxy proxy = Activator. createInstance (tmpType, new object [] {instance}) as RealProxy; return proxy. getTransparentProxy ();}}}Auxiliary Tools

Simple Demo

Public class HomeController: Controller {// GET:/Home/public ActionResult Index () {Service service = new Service (); Service proxy = Common. delayProxyUtil. getTransparentProxy (typeof (Service), service) as Service; proxy. test (); return View () ;}} public class Service: externalbyrefobject {public void Test () {Console. writeLine ("Call the Test method ");}}View Code

 

Because the example is very simple, we will not upload the source code.

To be continued...

 

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.