This article focuses on the ASP. NET Core Lightweight AOP solution: Aspectcore, the friend you need can refer to the following
What is Aspectcore Project?
Aspectcore Project is a lightweight Aop (aspect-oriented programming) solution for the ASP. NET core platform, which better adheres to the modular development concept of ASP. Using Aspectcore makes it easier to build low-coupling, easy-to-scale Web applications. Aspectcore uses emit to implement efficient dynamic proxies without relying on any third-party AOP libraries.
Open to use the Aspectcore
Start Visual Studio. From the File menu, choose New > Project. Select the ASP. NET core Web application project template to create a new ASP. NET core Web application project.
Install AspectCore.Extensions.DependencyInjection package from Nuget:
Pm> Install-package AspectCore.Extensions.DependencyInjection
In general, you can use the abstract Interceptorattribute custom attribute class, which implements the Iinterceptor interface. The Aspectcore is implemented by default with an attribute-based interceptor configuration. Our custom interceptors look like this:
public class custominterceptorattribute:interceptorattribute{public async override Task Invoke (iaspectcontext Context, Aspectdelegate next) { try { Console.WriteLine ("Before Service call"); Await next (context); } catch (Exception) { Console.WriteLine ("Service threw an exception!"); throw; } Finally { Console.WriteLine ("After service call"); } }}
Define the Icustomservice interface and its implementation class Customservice:
public interface icustomservice{ [custominterceptor] void Call ();} public class customservice:icustomservice{public void Call () { Console.WriteLine ("Service Calling ..."); }}
Inject Icustomservice into the HomeController:
public class homecontroller:controller{ private readonly icustomservice _service; Public HomeController (Icustomservice service) { _service = service; } Public Iactionresult Index () { _service. Call (); return View ();} }
Register Icustomservice, and then, in Configureservices, configure the container to create the proxy type:
Public IServiceProvider configureservices (iservicecollection services) { services. Addtransient<icustomservice, customservice> (); Services. Addmvc (); Services. Addaspectcore (); Return services. Buildaspectcoreserviceprovider ();}
Interceptor configuration. First install the AspectCore.Extensions.Configuration package:
Pm> Install-package AspectCore.Extensions.Configuration
Global Interceptor. AddAspectCore(Action<AspectCoreOptions>)
the overloaded method used, where aspectcoreoptions provides interceptorfactories to register the global Interceptor:
Services. Addaspectcore (config = = { config. Interceptorfactories.addtyped<custominterceptorattribute> (); });
Global interceptor with constructor parameters, CustomInterceptorAttribute
add a constructor with parameters in:
public class custominterceptorattribute:interceptorattribute{ private readonly string _name; Public Custominterceptorattribute (string name) { _name = name; } Public async override Task Invoke (aspectcontext context, aspectdelegate next) { try { Console.WriteLine ("Before Service call"); Await next (context); } catch (Exception) { Console.WriteLine ("Service threw an exception!"); throw; } Finally { Console.WriteLine ("After service call"); } }}
To modify the global Interceptor registration:
Services. Addaspectcore (config =>{ config. Interceptorfactories.addtyped<custominterceptorattribute> (args:new object[] {"Custom"});
As a global interceptor for the service. Add in Configureservices:
Services. Addtransient<custominterceptorattribute> (Provider = new Custominterceptorattribute ("service"));
To modify the global Interceptor registration:
Services. Addaspectcore (config =>{ config. Interceptorfactories.addserviced<custominterceptorattribute> ();});
Global interceptor acting on a specific service or method, the following code demonstrates a global interceptor that acts on a class with a service suffix:
Services. Addaspectcore (config =>{ config. Interceptorfactories.addtyped<custominterceptorattribute> (method = method). DeclaringType.Name.EndsWith ("Service");});
A specific global interceptor that uses wildcards:
Services. Addaspectcore (config =>{ config. Interceptorfactories.addtyped<custominterceptorattribute> (Predicatefactory.forservice ("*Service");});
Provide nonaspectattribute in Aspectcore to enable service or method not to be proxied:
[Nonaspect]public interface icustomservice{ void Call ();}
The global ignore configuration is supported, and wildcard characters are also supported:
Services. Addaspectcore (config = service under the {//app1) namespace will not be Proxy config. Nonaspectoptions.addnamespace ("App1"); Service in the last-level APP1 namespace will not be Proxy config. Nonaspectoptions.addnamespace ("*. App1 "); The Icustomservice interface is not proxy config. Nonaspectoptions.addservice ("Icustomservice"); Interfaces and classes that are suffixed with service will not be Proxy config. Nonaspectoptions.addservice ("*service"); The method named query is not Proxy config. Nonaspectoptions.addmethod ("Query"); The method with the suffix query will not be Proxy config. Nonaspectoptions.addmethod ("*query"); });
The dependency injection in the interceptor. attribute injection, constructor injection, and service locator mode are supported in interceptors.
attribute injection, which has the property tag [] (distinct from) attribute of public get and set permission in the Interceptor, is AspectCore.Abstractions.FromServices
Microsoft.AspNetCore.Mvc.FromServices
automatically injected into the property, such as:
public class custominterceptorattribute:interceptorattribute{ [AspectCore.Abstractions.FromServices] Public ilogger<custominterceptorattribute> Logger {get; set;} public override Task Invoke (aspectcontext context, aspectdelegate next) { logger.loginformation ("Call Interceptor "); Return to next (context);} }
Constructor injection requires the interceptor to be a service, and in addition to the global interceptor, the interceptor can still be activated from di using serviceinterceptor:
public interface icustomservice{ [Serviceinterceptor (typeof (Custominterceptorattribute))] void call ();
Service Locator mode. The interceptor context Aspectcontext can get the serviceprovider of the current scoped:
public class custominterceptorattribute:interceptorattribute{public override Task Invoke (Aspectcontext context, Aspectdelegate next) { var logger = context. Serviceprovider.getservice<ilogger<custominterceptorattribute>> (); Logger. Loginformation ("Call Interceptor"); Return to next (context);} }
Use AUTOFAC and Aspectcore. Aspectcore native support for integrated AUTOFAC, we need to install the following two NuGet packages:
pm> install-package autofac.extensions.dependencyinjectionpm> install-package ASPECTCORE.EXTENSIONS.AUTOFAC
Aspectcore provides Registeraspectcore extension methods to register the services required by dynamic agents in the container of AUTOFAC. The Asinterfacesproxy and Asclassproxy extension methods are provided to enable interface and class proxies. Modify the Configureservices method to:
public IServiceProvider configureservices (iservicecollection services) {services. Addmvc (); var container = new Containerbuilder (); Container. Registeraspectcore (); Container. Populate (services); Container. Registertype<customservice> (). As<icustomservice> (). Instanceperdependency (). Asinterfacesproxy (); return new Autofacserviceprovider (container. Build ());}