C#Implement Dynamic AOP Framework with Emit

Posted by metrostars on Thu, 07 Nov 2019 19:37:11 +0100

Before implementing DynamicProxy, introduce several necessary auxiliary classes:

1. Slice context class AspectContext

This class is used as a parameter to the OnEntry and OnEixt methods of the facet attribute class, which contains the proxy object Sender, the method name (Name) being cut in, the parameter list (Args) calling the method, and the return value (Result)

 1  public class AspectContext
 2  {
 3 
 4         #region Constructor
 5         /// <summary>
 6         /// Constructor
 7         /// </summary>
 8         /// <param name="sender">Object to be cut in</param>
 9         /// <param name="name">Cut-in method name</param>
10         /// <param name="args">Call Parameters</param>
11         public AspectContext(object sender, string name, object[] args)
12         {
13             Sender = sender; Name = name; Args = args; Result = null;
14         }
15         #endregion
16 
17         #region attribute
18 
19         /// <summary>
20         /// Object to be cut in
21         /// </summary>
22         public object Sender { get; set; }
23 
24         /// <summary>
25         ///Cut-in method name
26         /// </summary>
27         public string Name { get; set; }
28 
29         /// <summary>
30         /// Method Call Parameters
31         /// </summary>
32         public object[] Args { get; set; }
33 
34         /// <summary>
35         /// Return value
36         /// </summary>
37         public object Result { get; set; }
38 
39         #endregion
40     }

2. AspectAttribute

  /// <summary>
  /// Cutting Properties Base Class
  /// </summary>
  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property)]
  public abstract class AspectAttribute : Attribute
  {
        public AspectAttribute()
        {
            IntercepType = XAOP.IntercepType.All;
        }

        public abstract InterceptType InterceptType { get; set; }

        public abstract void OnEntry(AspectContext context);

        public abstract void OnExit(AspectContext context);
   }

This class is the base class for all facet attributes and contains intercept types, method call entries, and method call exits.

3. InterceptType of Intercept

  /// <summary>
  /// Interception type
  /// </summary>
   public enum InterceptType
   {
        #region enum

        /// <summary>
        /// Entrance
        /// </summary>
        OnEntry = 1,

        /// <summary>
        /// Exit
        /// </summary>
        OnExit = 2,

        /// <summary>
        /// All
        /// </summary>
        All = 3

        #endregion
    }

IV. Log Attribute Class

This class simply implements logging before and after method calls.

    /// <summary>
    /// Log characteristics
    /// </summary>
    public class LogAttribute : AspectAttribute
    {
        public override InterceptType InterceptType { get; set; }

        #region Start Call
        /// <summary>
        /// Start Call
        /// </summary>
        /// <param name="context"></param>
        public override void OnEntry(AspectContext context)
        {
            Console.Write("Log OnEntry:");

            if (context != null && context.Args != null)
                Console.WriteLine("{0}({1})", context.Name, string.Join(",", context.Args));
        }
        #endregion

        #region End of Call
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        public override void OnExit(AspectContext context)
        {
            Console.WriteLine("Log OnExit: " + context.Name + (context.Result != null ? " Result: " + context.Result.ToString() : "") + "\r\n");
        }
        #endregion
    }

Topics: C# Attribute