SoFunction
Updated on 2024-11-21

Core Lightweight Aop Solution: AspectCore

What is AspectCore Project ?

AspectCore Project is a lightweight Aop for the Core platform (Aspect-oriented programming) solution , it is better to follow Core's modular development concepts , the use of AspectCore can be more easily build low-coupling , easy to extend the Web application . AspectCore uses Emit to achieve efficient dynamic proxy so as not to rely on any third-party Aop library .

Enabling the use of AspectCore

Start Visual Studio. from the File menu, select New > Project. select the Core Web Application project template to create a new Core Web Application project.

  • Install the package from Nuget.
  • PM>   Install-Package
  • In general you can use the abstract InterceptorAttribute custom feature class, which implements the IInterceptor interface.AspectCore implements Attribute-based interceptor configuration by default. Our custom interceptor looks like the following.
public class CustomInterceptorAttribute : InterceptorAttribute
{
  public async override Task Invoke(IAspectContext context, AspectDelegate next)
  {
    try
    {
      ("Before service call");
      await next(context);
    }
    catch (Exception)
    {
      ("Service threw an exception!");
      throw;
    }
    finally
    {
      ("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()
  {
    ("service calling...");
  }
}

Injecting ICustomService in HomeController:

public class HomeController : Controller
{
  private readonly ICustomService _service;
  public HomeController(ICustomService service)
  {
    _service = service;
  }
  public IActionResult Index()
  {
    _service.Call();
    return View();
  }
}

Register the ICustomService, followed by configuring the container that creates the proxy type in ConfigureServices:.

public IServiceProvider ConfigureServices(IServiceCollection services)
{
  <ICustomService, CustomService>();
  ();
  ();
  return ();
}

Interceptor configuration. First install the package:

PM> Install-Package 

Global Interceptor. Use theAddAspectCore(Action<AspectCoreOptions>)overloaded methods, where AspectCoreOptions provides InterceptorFactories to register global interceptors:.

 (config =>
 {
   <CustomInterceptorAttribute>();
 });

Global interceptors with constructor parameters in theCustomInterceptorAttributeAdd a constructor with parameters to the

public class CustomInterceptorAttribute : InterceptorAttribute
{
  private readonly string _name;
  public CustomInterceptorAttribute(string name)
  {
    _name = name;
  }
  public async override Task Invoke(AspectContext context, AspectDelegate next)
  {
    try
    {
      ("Before service call");
      await next(context);
    }
    catch (Exception)
    {
      ("Service threw an exception!");
      throw;
    }
    finally
    {
      ("After service call");
    }
  }
}

Modify Global Interceptor Registration.

(config =>
{
   <CustomInterceptorAttribute>(args: new object[] { "custom" });
});

as a global interceptor for the service. Add it in ConfigureServices:

<CustomInterceptorAttribute>(provider => new CustomInterceptorAttribute("service"));

Modify Global Interceptor Registration.

(config =>
{
  <CustomInterceptorAttribute>();
});

A global interceptor that acts on a specific Service or Method, the following code demonstrates a global interceptor that acts on a class with a Service suffix:

(config =>
{
  <CustomInterceptorAttribute>(method => ("Service"));
});

Specific global interceptors using wildcards:

(config =>
{
  <CustomInterceptorAttribute>(("*Service"));
});

Provide NonAspectAttribute in AspectCore to make the Service or Method not be proxied:

[NonAspect]
public interface ICustomService
{
  void Call();
}

Global ignore configuration is also supported, as well as wildcards:

 (config =>
 {
   Services in the //App1 namespace are not proxied.
   ("App1");
   //Services under the namespace whose last level is App1 will not be proxied.
   ("*.App1");
   The //ICustomService interface will not be proxied.
   ("ICustomService");
   // Interfaces and classes suffixed with Service will not be proxied.
   ("*Service");
   // Methods named Query are not proxied.
   ("Query");
   // Methods with the suffix Query are not proxied.
   ("*Query");
 });

Dependency Injection in Interceptors. Support for property injection in interceptors
Attribute injection, attribute tags with public get and set permissions in the interceptor [] (as distinguished from) feature, the property can be injected automatically, for example:

public class CustomInterceptorAttribute : InterceptorAttribute
{
  []
  public ILogger<CustomInterceptorAttribute> Logger { get; set; }
  public override Task Invoke(AspectContext context, AspectDelegate next)
  {
    ("call interceptor");
    return next(context);
  }
}

Constructor injection is required to make the interceptor act as a Service, which can still be activated from the DI using ServiceInterceptor in addition to the global interceptor:

public interface ICustomService
{
  [ServiceInterceptor(typeof(CustomInterceptorAttribute))]
  void Call();
}

The interceptor context AspectContext gets the current Scoped ServiceProvider:

public class CustomInterceptorAttribute : InterceptorAttribute
{
  public override Task Invoke(AspectContext context, AspectDelegate next)
  {
    var logger = <ILogger<CustomInterceptorAttribute>>();
    ("call interceptor");
    return next(context);
  }
}

Using Autofac and AspectCore. AspectCore natively supports integration with Autofac, we need to install the following two nuget packages:

PM> Install-Package 
PM> Install-Package 

AspectCore provides RegisterAspectCore extension method to register the services needed for dynamic proxying in Autofac's Container, and AsInterfacesProxy and AsClassProxy extension methods to enable interface and class proxying. Modify the ConfigureServices method to:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
  ();
  var container = new ContainerBuilder();
  ();
  (services);
  <CustomService>().As<ICustomService>().InstancePerDependency().AsInterfacesProxy();

  return new AutofacServiceProvider(());
}

Feedback with questions

If you have any questions, please submit an Issue to us.

AspectCore Project Project address./aspectcore

The above is a small introduction to the Core lightweight Aop solution: AspectCore, I hope to help you, if you have any questions please leave me a message, I will reply to you in a timely manner. I would also like to thank you very much for your support of my website!