Asp.Net Core轻量级Aop解决方案:AspectCore

2025-05-29 0 92

什么是AspectCore Project ?

core" title="AspectCore">AspectCore Project 是适用于Asp.Net Core 平台的轻量级 Aop(Aspect-oriented programming) 解决方案,它更好的遵循Asp.Net Core的模块化开发理念,使用core" title="AspectCore">AspectCore可以更容易构建低耦合、易扩展的Web应用程序。core" title="AspectCore">AspectCore使用Emit实现高效的动态代理从而不依赖任何第三方Aop库。

开使使用core" title="AspectCore">AspectCore

启动 Visual Studio。从 File 菜单, 选择 New > Project。选择 ASP.NET Core Web Application 项目模版,创建新的 ASP.NET Core Web Application 项目。

  • 从 Nuget 安装 core" title="AspectCore">AspectCore.Extensions.DependencyInjection package:
  • PM> Install-Package core" title="AspectCore">AspectCore.Extensions.DependencyInjection
  • 在一般情况下可以使用抽象的InterceptorAttribute自定义特性类,它实现IInterceptor接口。core" title="AspectCore">AspectCore默认实现了基于Attribute的拦截器配置。我们的自定义拦截器看起来像下面这样:
?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20
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");

}

}

}

定义ICustomService接口和它的实现类CustomService:

?

1

2

3

4

5

6

7

8

9

10

11

12
public interface ICustomService

{

[CustomInterceptor]

void Call();

}

public class CustomService : ICustomService

{

public void Call()

{

Console.WriteLine("service calling...");

}

}

在HomeController中注入ICustomService:

?

1

2

3

4

5

6

7

8

9

10

11

12

13
public class HomeController : Controller

{

private readonly ICustomService _service;

public HomeController(ICustomService service)

{

_service = service;

}

public IActionResult Index()

{

_service.Call();

return View();

}

}

注册ICustomService,接着,在ConfigureServices中配置创建代理类型的容器:

?

1

2

3

4

5

6

7
public IServiceProvider ConfigureServices(IServiceCollection services)

{

services.AddTransient<ICustomService, CustomService>();

services.AddMvc();

services.AddAspectCore();

return services.BuildAspectCoreServiceProvider();

}

拦截器配置。首先安装core" title="AspectCore">AspectCore.Extensions.Configuration package:

?

1
PM> Install-Package AspectCore.Extensions.Configuration

全局拦截器。使用AddAspectCore(Action<AspectCoreOptions>)的重载方法,其中core" title="AspectCore">AspectCoreOptions提供InterceptorFactories注册全局拦截器:

?

1

2

3

4
services.AddAspectCore(config =>

{

config.InterceptorFactories.AddTyped<CustomInterceptorAttribute>();

});

带构造器参数的全局拦截器,在CustomInterceptorAttribute中添加带参数的构造器:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25
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");

}

}

}

修改全局拦截器注册:

?

1

2

3

4
services.AddAspectCore(config =>

{

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

});

作为服务的全局拦截器。在ConfigureServices中添加:

?

1
services.AddTransient<CustomInterceptorAttribute>(provider => new CustomInterceptorAttribute("service"));

修改全局拦截器注册:

?

1

2

3

4
services.AddAspectCore(config =>

{

config.InterceptorFactories.AddServiced<CustomInterceptorAttribute>();

});

作用于特定Service或Method的全局拦截器,下面的代码演示了作用于带有Service后缀的类的全局拦截器:

?

1

2

3

4
services.AddAspectCore(config =>

{

config.InterceptorFactories.AddTyped<CustomInterceptorAttribute>(method => method.DeclaringType.Name.EndsWith("Service"));

});

使用通配符的特定全局拦截器:

?

1

2

3

4
services.AddAspectCore(config =>

{

config.InterceptorFactories.AddTyped<CustomInterceptorAttribute>(PredicateFactory.ForService("*Service"));

});

core" title="AspectCore">AspectCore中提供NonAspectAttribute来使得Service或Method不被代理:

?

1

2

3

4

5
[NonAspect]

public interface ICustomService

{

void Call();

}

同时支持全局忽略配置,亦支持通配符:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15
services.AddAspectCore(config =>

{

//App1命名空间下的Service不会被代理

config.NonAspectOptions.AddNamespace("App1");

//最后一级为App1的命名空间下的Service不会被代理

config.NonAspectOptions.AddNamespace("*.App1");

//ICustomService接口不会被代理

config.NonAspectOptions.AddService("ICustomService");

//后缀为Service的接口和类不会被代理

config.NonAspectOptions.AddService("*Service");

//命名为Query的方法不会被代理

config.NonAspectOptions.AddMethod("Query");

//后缀为Query的方法不会被代理

config.NonAspectOptions.AddMethod("*Query");

});

拦截器中的依赖注入。在拦截器中支持属性注入,构造器注入和服务定位器模式。
属性注入,在拦截器中拥有public get and set权限的属性标记[AspectCore.Abstractions.FromServices](区别于Microsoft.AspNetCore.Mvc.FromServices)特性,即可自动注入该属性,如:

?

1

2

3

4

5

6

7

8

9

10
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 next(context);

}

}

构造器注入需要使拦截器作为Service,除全局拦截器外,仍可使用ServiceInterceptor使拦截器从DI中激活:

?

1

2

3

4

5
public interface ICustomService

{

[ServiceInterceptor(typeof(CustomInterceptorAttribute))]

void Call();

}

服务定位器模式。拦截器上下文AspectContext可以获取当前Scoped的ServiceProvider:

?

1

2

3

4

5

6

7

8

9
public class CustomInterceptorAttribute : InterceptorAttribute

{

public override Task Invoke(AspectContext context, AspectDelegate next)

{

var logger = context.ServiceProvider.GetService<ILogger<CustomInterceptorAttribute>>();

logger.LogInformation("call interceptor");

return next(context);

}

}

使用Autofac和core" title="AspectCore">AspectCore。core" title="AspectCore">AspectCore原生支持集成Autofac,我们需要安装下面两个nuget packages:

?

1

2
PM> Install-Package Autofac.Extensions.DependencyInjection

PM> Install-Package AspectCore.Extensions.Autofac

core" title="AspectCore">AspectCore提供Registercore" title="AspectCore">AspectCore扩展方法在Autofac的Container中注册动态代理需要的服务,并提供AsInterfacesProxy和AsClassProxy扩展方法启用interface和class的代理。修改ConfigureServices方法为:

?

1

2

3

4

5

6

7

8

9

10
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());

}

有问题反馈

如果您有任何问题,请提交 Issue 给我们。

core" title="AspectCore">AspectCore Project 项目地址: https://github.com/aspectcore

以上所述是小编给大家介绍的Asp.Net Core轻量级Aop解决方案:core" title="AspectCore">AspectCore,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对快网idc网站的支持!

原文链接:http://www.cnblogs.com/liuhaoyang/p/aspectcore-introduction-1.html

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 Asp.Net Core轻量级Aop解决方案:AspectCore https://www.kuaiidc.com/99204.html

相关文章

发表评论
暂无评论