Preface
aop is the most well-known of the many Aop frameworks. Castle is also the dead. Of course, the .NET Core community rookie AspectCore is very excellent in performance and functions. It has gradually been praised by the community and is used by more and more people. Thanks to Lemon for the gift!
If you want to implement an Aop out of your own needs or learning, do you think you need to use Emit to do it? Recently I learned about this corefx class library, which has implemented the dynamic proxy function.
1|
Here is a demonstration of how to use it:
class Program { static void Main(string[] args) { //Create a proxy class and inject SampleProxy as an interceptor var sampleProxy = (targetInterface)<targetInterface, SampleProxy>(); //Execute the interface method ("here is invoke by proxy"); } } //The interface that needs to be generated with a proxy instancepublic interface targetInterface { //This method will be implemented by the proxy class void Write(string writesomeshing); } public class SampleProxy : DispatchProxy { /// <summary> /// Intercept the call /// </summary> /// <param name="method">Intercepted method information</param> /// <param name="parameters">The parameter passed in the intercepted method refers to</param> /// <returns></returns> protected override object Invoke(MethodInfo targetMethod, object[] args) { (args[0]); return null; } }
2|0 transformed into a simple AOP
2|1 Why?
There is only one API, which is object Create<T,TProxy>() where TProxy:DispatchProxy, which restricts that only generic parameters can be passed in and types cannot be passed from methods, which will bring many problems. What's even more annoying is that after I asked the official issue, I still did not add this API...
2|2 Renovation method
Fortunately, under that issue, the issue author provided a solution, which is to construct this generic method using reflection. On this basis, I also encapsulated the functions of incoming interceptor instance and incoming interceptor constructor method parameters.
/// <summary> /// Interceptor interface/// </summary> public interface IInterceptor { /// <summary> /// Interceptor call /// </summary> /// <param name="target">Proxy instance</param> /// <param name="method">Method intercepted</param> /// <param name="parameters">Parameter values passed in by the intercepted method</param> /// <returns>The return value will be passed to the method return value</returns> object Intercept(object target, MethodInfo method, object[] parameters); }
To implement this interface by the interceptor, the following is the encapsulation of DispatchProxy to implement more methods to create proxy instances.
public class ProxyGenerator : DispatchProxy { private IInterceptor interceptor { get; set; } /// <summary> /// Create a proxy instance /// </summary> /// <param name="targetType">Interface type to be proxyed</param> /// <param name="interceptor">interceptor</param> /// <returns>Proxy instance</returns> public static object Create(Type targetType, IInterceptor interceptor) { object proxy = GetProxy(targetType); ((ProxyGenerator)proxy).CreateInstance(interceptor); return proxy; } /// <summary> /// Create a proxy instance /// </summary> /// <param name="targetType">Interface type to be proxyed</param> /// <param name="interceptorType">Interceptor type</param> /// <param name="parameters">Interceptor constructor parameter value</param> /// <returns>Proxy instance</returns> public static object Create(Type targetType, Type interceptorType, params object[] parameters) { object proxy = GetProxy(targetType); ((ProxyGenerator)proxy).CreateInstance(interceptorType, parameters); return proxy; } /// <summary> /// Create a proxy instance TTarget: The interface type to be proxy TInterceptor: Interceptor type /// </summary> /// <param name="parameters">Interceptor constructor parameter value</param> /// <returns>Proxy instance</returns> public static TTarget Create<TTarget, TInterceptor>(params object[] parameters) where TInterceptor : IInterceptor { var proxy = GetProxy(typeof(TTarget)); ((ProxyGenerator)proxy).CreateInstance(typeof(TInterceptor), parameters); return (TTarget)proxy; } private static object GetProxy(Type targetType) { var callexp = (typeof(DispatchProxy), nameof(), new[] { targetType, typeof(ProxyGenerator) }); return <Func<object>>(callexp).Compile()(); } private void CreateInstance(Type interceptorType, object[] parameters) { var ctorParams = (x => ()).ToArray(); var paramsExp = (x => (x)); var newExp = ((ctorParams), paramsExp); = <Func<IInterceptor>>(newExp).Compile()(); } private void CreateInstance(IInterceptor interceptor) { = interceptor; } protected override object Invoke(MethodInfo method, object[] parameters) { return (method, parameters); } }
2|3 How to use
class Program { static void Main(string[] args) { var poxy1 = (targetInterface)(typeof(targetInterface), new SampleProxy("coreproxy1")); ("here was invoked"); //---> "here was invoked by coreproxy1" var poxy2 = (targetInterface)(typeof(targetInterface), typeof(SampleProxy), "coreproxy2"); ("here was invoked"); //---> "here was invoked by coreproxy2" var poxy3 = <targetInterface, SampleProxy>("coreproxy3"); ("here was invoked"); //---> "here was invoked by coreproxy3" } } public class SampleProxy : IInterceptor { private string proxyName { get; } public SampleProxy(string name) { = name; } public object Intercept(MethodInfo method, object[] parameters) { (parameters[0] + " by " + proxyName); return null; } } public interface targetInterface { void Write(string writesome); }
3|0 Summary
To sum up, the wheel given to us by Microsoft's father is both light and easy to use.
The example code for this article can be found on my github: /ElderJames/CoreProxy
Okay, the above is the entire content of this article. I hope that the content of this article has a certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support.