Self-implemented simple AOP (2) Introduce Attribute to specify the enhancement object for the method, aopattribute

Source: Internet
Author: User

Self-implemented simple AOP (2) Introduce Attribute to specify the enhancement object for the method, aopattribute

Preface: Self-Implementation of simple AOP (I)

 

In the previous article, I briefly introduced the implementation of AOP. Next, Attribute is introduced to specify the enhancement object for the method to implement a simple AOP.

Note: It specifies the enhancement object, "object", that is, Attribute tag, which is actually an object. With polymorphism, you can easily implement enhanced scaling.

 

Custom Attribute

/// <Summary> /// mark the specified enhancement object for the method // <para> the specified enhancement, </para> /// </summary> [AttributeUsage (AttributeTargets. method, Inherited = false, AllowMultiple = false)] public sealed class AdviceAttribute: attribute {// <summary> // enhancement object // </summary> public AdviceAbstract Advice {get; private set ;} /// <summary> /// use the default enhancement object of the specified type /// <para> If the type is null, no enhancement is used </para> /// </para>/ summary> // <param name = "type"> </param> public AdviceAttribute (Type type): this (type, string. empty) {}/// <summary> /// use the public static method name to initialize the enhancement object of the specified type. /// <para> If the type is null, no enhancement is used. </para> /// </summary> /// <param name = "type"> type </param> /// <param name = "methodName"> // public static method Name // <para> If the method name is empty, call the default constructor </para> /// </param> public AdviceAttribute (Type type, string methodName) {// if the type is null, no enhancement if (type = null) {this. advice = null; return;} if (string. isNullOrWhiteSpace (methodName) {this. advice = Activator. createInstance (type) as AdviceAbstract; return;} this. advice = type. invokeMember (methodName, System. reflection. bindingFlags. invokeMethod | System. reflection. bindingFlags. public | System. reflection. bindingFlags. static, null) as AdviceAbstract;} # region the following two methods do not work very well and are not recommended, therefore, the constructor is private. // <summary> // use the parameter list to initialize the object of the specified type. // </summary> /// <param name = "type"> type </param> /// <param name = "objs"> parameter list </param> private AdviceAttribute (type Type, params object [] objs) {this. advice = Activator. createInstance (type, objs) as AdviceAbstract ;} /// <summary> /// use the name parameter to initialize the enhancement object of the specified type. // </summary> /// <param name = "namedParameter"> // the name parameter list of the form parameters separated by colons and semicolons // <para> supports the following data types: string, int, bool and types that can be deserialized by static Parse </para> /// </param> /// <param name = "type"> </param> private AdviceAttribute (string namedParameter, type type) {this. advice = ReflectionUtil. invokeConstructor (type, namedParameter) as AdviceAbstract;} # endregion}Attribute

 

Enhanced abstract classes and custom enhancements

/// <Summary> // abstract enhancement class /// </summary> public abstract class AdviceAbstract {public abstract IMessage Invoke (externalbyrefobject target, IMethodCallMessage callMessage );} public class MyAdvice: AdviceAbstract {public override IMessage Invoke (financialbyrefobject target, IMethodCallMessage callMessage) {this. beforeInvoke (target); IMessage message = DelayProxyUtil. invokeBeProxy (target, callMessage); this. afterInvoke (target); return message;} protected virtual void BeforeInvoke (financialbyrefobject target) {Console. writeLine ("Before");} protected virtual void AfterInvoke (financialbyrefobject target) {Console. writeLine ("After ");}}Advice

 

With the above two components, and with the aid of the proxy class DelayProxy <T>, the enhanced weaving will be achieved, and the simple AOP has become a prototype.

/// <Summary> /// proxy class that supports generics and delayed initialization. It can be used as a proxy for subtypes of externalbyrefobject. /// <para> During proxy execution, obtain the enhancement specified by AdviceAttribute and weave the enhancement </para> /// </summary> public class DelayProxy <T>: RealProxy where T: export albyrefobject {private static object objLock = new object (); // <summary> // the object to be proxy /// </summary> private T target; /// <summary> /// whether to delay initialization /// <para> True: delay, False: no delay </para> /// </summary> private Readonly bool delay; public DelayProxy (T target, bool delay): base (typeof (T) {this.tar get = target; this. delay = delay ;} /// <summary> /// call the proxy object /// <para> supports the out ref parameter </para> /// </summary> /// <param name = "msg"> </param> // <returns> </returns> public override IMessage Invoke (IMessage msg) {if (this. delay & this.tar get = null) {lock (objLock) {if (this. delay & this.tar get = null ){ T instance = Activator. createInstance (typeof (T) as T; // automatically assemble attributes // enable proxy for Attribute objects and delay the initialization of objects to be proxies // DelayProxyUtil. autowiredProperties (instance); this.tar get = instance ;}} IMethodCallMessage callMessage = (IMethodCallMessage) msg; AdviceAttribute attri = ReflectionUtil. getCustomAttribute <AdviceAttribute> (callMessage. methodBase); if (attri! = Null & attri. Advice! = Null) {return attri.Advice.Invoke(this.tar get, callMessage);} return DelayProxyUtil.InvokeBeProxy(this.tar get, callMessage );}}DelayProxy

 

Source code (MVC4 project does not have packages folder): http://files.cnblogs.com/files/08shiyan/AOPDemo.zip

The source code also implements delayed initialization of the proxy object.

 

To be continued...

 

Related Article

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.