Nuget library address:/packages//
Github library address:/whuanle/
It is a simple and lightweight AOP framework written based on EMIT, supports non-invasive proxy, supports .NET Core/Core, and supports multiple dependency injection frameworks.
1. Quick Start
Use is relatively simple, you only need to use[Interceptor]
Feature tags the type that requires proxy, and then use inheritanceActionAttribute
The attribute marks the method or attribute to be proxyed.
1.1 Inheriting ActionAttribute Features
ActionAttribute
It is a feature mark used for proxy methods or attributes. It cannot be used directly. The method needs to be inherited and rewrited.
Examples are as follows:
public class LogAttribute : ActionAttribute { public override void Before(AspectContext context) { ("Before execution"); } public override object After(AspectContext context) { ("After execution"); if () return ; else if () return ; return null; } }
Before
It will take effect before the proxy method is executed or when the proxy attribute is called, you can useAspectContext
Context, obtain and modify passed parameters.
After takes effect after the method is executed or when the property is called, you can get and modify the return value through the context.
1.2 Tag proxy type
In the type being proxyed, use[Interceptor]
Features are marked, and in methods that require proxy, inheritedActionAttribute
characteristics to mark.
This method is invasive and needs to be done before compilation.
[Interceptor] public class Test : ITest { [Log] public virtual string A { get; set; } [Log] public virtual void MyMethod() { ("Running"); } }
Note that a method or property can only set one interceptor.
2. How to create a proxy type
There are many ways to generate proxy types, and the following is a simple way.
Please create the following code in advance:
public class LogAttribute : ActionAttribute { public override void Before(AspectContext context) { ("Before execution"); } public override object After(AspectContext context) { ("After execution"); if () return ; else if () return ; return null; } } public interface ITest { void MyMethod(); } [Interceptor] public class Test : ITest { [Log] public virtual string A { get; set; } public Test() { ("Constructor is OK"); } [Log] public virtual void MyMethod() { ("Running"); } }
2.1 Create directly through the API
ByAopInterceptor
Class, you can generate proxy types.
Examples are as follows:
ITest test1 = <ITest, Test>(); Test test2 = <Test>(); (); ();
CreateProxyOfInterface
Create proxy types through interfaces;CreateProxyOfClass
Create proxy types through classes;
The default call is the parameterless constructor.
3. Create a proxy type
Through API
You can refer to the source code solution
The ExampleConsole project in .
If you want to use it directlyand
Method, create proxy types through interfaces or classes.
ITest test1 = <ITest, Test>(); Test test2 = <Test>();
If you want to specify an instantiated constructor, you can do this:
// Specify the constructor test2 = <Test>("aaa", "bbb"); ();
pass
is the default dependency injection container for .NET Core/Core.
If you need to support the use of AOP in Core, you can install it in the Nuget package.。
If you use it under the console, you can use the name
BuildAopProxy
ofIServiceCollection
Expand method to generate proxy types for the types in the container.
Examples are as follows:
IServiceCollection _services = new ServiceCollection(); _services.AddTransient<ITest, Test>(); var serviceProvider = _services.BuildAopProxy().BuildServiceProvider(); <ITest>(); return serviceProvider;
You can refer to the source code solutionExampleMEDI
project.
If you want to use it in Core, you canStartup
middle,ConfigureServices
The last line of code of the method is used();
。
public void ConfigureServices(IServiceCollection services) { (); (); }
Can also be inProgram
ofIHostBuilder
Used in.UseServiceProviderFactory(new AOPServiceProxviderFactory())
To configure and use .
Example:
public static IHostBuilder CreateHostBuilder(string[] args) => (args) .UseServiceProviderFactory(new AOPServiceProxviderFactory()) .ConfigureWebHostDefaults(webBuilder => { <Startup>(); });
You can refer to the solutionExampleConsole
andExampleWebMEDI
Two projects.
You don't have to worry that using dependency injection will slow down the program or destroy the original properties in the container after introduction. Only the types that need to be proxyed will be processed when creating the container, and will not affect the services in the container, nor will it interfere with the execution of dependency injection.
By Autofac
If you need to use AOP in Autofac, you need to referenceBag.
If you use Autofac in a console program, you canBuild()
Use laterBuildAopProxy()
。
ContainerBuilder builder = new ContainerBuilder(); <Test>().As<ITest>(); var container = ().BuildAopProxy(); using (ILifetimeScope scope = ()) { // Get an instance ITest myService = <ITest>(); (); } (); }
It should be noted that it can only be called after the completed component registration creates a new container.BuildAopProxy()
method,
In this way, for a new container, you can consider whether you need to proxy components in the container.
If you use Autofac in Core, you need to use it in the IHostBuilder of the Program class:
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
If you need a component that the proxy has registered, replace it with:
.UseServiceProviderFactory(new ())
Please refer to the source code solutionExampleAutofac
andExampleWebAutofac
Two projects.
4. In-depth use
Agent Type
The type to be proxy needs to be used[Interceptor]
To mark, for example:
[Interceptor] public class Test : ITest { }
Supports generic types.
The type that is proxy must be inheritable.
There are no restrictions on the constructor of the type, you can write it as you like.
When creating a proxy type using the API and instantiating it, you can specify which constructor to use.
For example:
string a="",b="",c=""; ITest test1 = <ITest, Test>(a,b,c);
The API will automatically find the appropriate constructor based on the number of parameters and the type of parameters.
Methods, attribute agents
In order to proxy methods or attributes, you need to inheritActionAttribute
Properties, then mark this property for the method or attribute, and set the method or attribute tovirtual
Different methods in a type can use different interceptors.
[Log1] public virtual void MyMethod1(){} [Log2] public virtual void MyMethod2(){}
For properties, you can use the properties directly on the properties, or only in the get or set constructor.
[Log] public virtual string A { get; set; } // or public virtual string A { [Log] get; set; } // or public virtual string A { get; [Log] set; }
If you use characteristics on attributes, it is equivalent to[Log] get; [Log] set;
。
Context
A simple method or property intercept tag is like this:
public class LogAttribute : ActionAttribute { public override void Before(AspectContext context) { ("Before execution"); } public override object After(AspectContext context) { ("After execution"); if () return ; else if () return ; return null; } }
The properties of AspectContext are described as follows:
Fields | illustrate |
---|---|
Type | The proxy type currently generated by the proxy type |
ConstructorParamters | The argument to the constructor used when the type is instantiated, = 0 if the constructor has no arguments, instead of MethodValues being null. |
IsProperty | The current intercepted attributes |
PropertyInfo | The information of the currently executed attribute may be null. |
PropertyValue | But when the property is called, it returns the result of get or the value of set. |
IsMethod | The current intercepting method |
MethodInfo | Information about the current method |
MethodValues | Parameters passed when the method is called, if this method has no parameters, then = 0 instead of MethodValues being null |
MethodResult | The result returned by the method execution (if any) |
Intercepting parameters of methods or attributes
With the context, you can modify the parameters of a method or property and intercept the return result:
public class LogAttribute : ActionAttribute { public override void Before(AspectContext context) { // Intercept and modify the method parameters for (int i = 0; i < ; i++) { [i] = (int)[i] + 1; } ("Before execution"); } public override object After(AspectContext context) { ("After execution"); // The execution result of the intercept method = (int) + 664; if () return ; else if () return ; return null; } } [Interceptor] public class Test { [Log] public virtual int Sum(int a, int b) { ("Running"); return a + b; } }
Test test = <Test>(); ((1, 1));
Method parameter supportin
、ref
、out
;Support generic properties of generic methods; supports asynchronous methods;
Non-invasive proxy
This method does not require changing the type being proxyed, you can also proxy the type in the assembly set.
public class LogAttribute : ActionAttribute { public override void Before(AspectContext context) { ("Before execution"); } public override object After(AspectContext context) { ("After execution"); if () return ; else if () return ; return null; } }
public class TestNo { public virtual string A { get; set; } public virtual void MyMethod() { ("Running"); } }
TestNo test3 = <TestNo>(new ProxyTypeBuilder() .AddProxyMethod(typeof(LogAttribute), typeof(TestNo).GetMethod(nameof())) .AddProxyMethod(typeof(LogAttribute), typeof(TestNo).GetProperty(nameof()).GetSetMethod()));
Build the proxy type with ProxyTypeBuilder.
Both proxy methods or attributes are usedAddProxyMethod
, the first parameter is the interceptor to be used, and the second parameter is the method to be intercepted.
If you want to intercept attributes, please set the attributes separately.get
、set
Construction.
If multiple methods or properties use the same interceptor, you can do this:
TestNo test3 = <TestNo>( new ProxyTypeBuilder(new Type[] { typeof(LogAttribute) }) .AddProxyMethod("LogAttribute", typeof(TestNo).GetMethod(nameof())) .AddProxyMethod("LogAttribute", typeof(TestNo).GetProperty(nameof()).GetSetMethod()));
TestNo test3 = <TestNo>( new ProxyTypeBuilder(new Type[] { typeof(LogAttribute) }) .AddProxyMethod("LogAttribute", typeof(TestNo).GetMethod(nameof())) .AddProxyMethod(typeof(LogAttribute2), typeof(TestNo).GetProperty(nameof()).GetSetMethod()));
Pass the interceptor you need in the constructor and then use it when intercepting.
This is the end of this article about Caizha Open Source AOP library (.NET Core) based on EMIT. For more content related to EMIT AOP library, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!