暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

ASP.NET Core中IOC使用之三(Autofac实现AOP)

码农游乐场 2021-09-08
2132

这篇文章是接着上一篇文章写的,如果没有看上一篇请点击下面这个链接。

ASP.NET Core中IOC使用之二(Autofac替换IOC容器)

实现AOP

新的.NET Core是基于.NET Standard的,所以我们在引用库的时候特别要注意相关的兼容问题。在传统的ASP.NET中,使用过Autofac来进行AOP操作的,应该都知道这个库. Autofac.Extras.DynamicProxy

Autofac的DynamicProxy来自老牌的Castle项目。DynamicProxy(以下称为动态代理)起作用主要是为我们的类生成一个代理类,这个代理类可以在我们调用原本类的方法之前,调用拦截器以实现AOP。那么动态代理是怎么实现的呢,这里简单一下提一下,这里主要是用了emit技术动态生成IL,相当于在内存中用IL给我们编写了一个Class。

添加Nuget包:Autofac.Extras.DynamicProxy


定义一个拦截器类,实现IInterceptor

    public class TestInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("你正在调用方法 \"{0}\" 参数是 {1}... ",
invocation.Method.Name,
string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray()));

invocation.Proceed();

Console.WriteLine("方法执行完毕,返回结果:{0}", invocation.ReturnValue);
}
}

复制

这里,需要继承IInterceptor,然后实现它的Intercept方法。我们直接将拦截内容输出到调试窗(正式项目请根据业务来操作拦截)。

修改Startup的ConfigureContainer方法

  • 拦截器注册要在使用拦截器的接口和类型之前

public void ConfigureDevelopmentContainer(ContainerBuilder builder)
{
// 要先注册拦截器
builder.RegisterType<TestInterceptor>();

注册的代码改成这样

builder.RegisterType<TopicService>().As<ITopicService>().EnableInterfaceInterceptors();

//如果需要在Controller中使用属性注入,需要在ConfigureContainer中添加如下代码
var controllerBaseType = typeof(ControllerBase);

builder.RegisterAssemblyTypes(typeof(Program).Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired()//允许属性注入
.EnableClassInterceptors();// 允许在Controller类上使用拦截器
}

复制

这里注意,一定要在你注入的服务后面加上EnableInterfaceInterceptors来开启你的拦截

在需要使用拦截器的类或接口上添加描述

[Intercept(typeof(TestInterceptor))]

复制
  1. 自定义服务上使用拦截器 我这里是定义了一个接口,如下:

[Intercept(typeof(TestInterceptor))]
public interface ITopicService
{
int Add(int a, int b);
}

复制

定义一个实现接口的类

 public class TopicService:ITopicService
{
public int Add(int a,int b)
{
return a + b;
}
}

复制

然后我们运行代码. 效果如下: 

  1. 在Controller上使用拦截器

[Intercept(typeof(TestInterceptor))]
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly ITopicService _service;

public HomeController(ILogger<HomeController> logger,ITopicService service)
{
_logger = logger;
_service = service;
}

public IActionResult Index()
{
return View();
}
}

复制

这只是个简单的Demo,我们就完成了使用Autofac进行AOP拦截。

动态代理是动态生成一个代理类,那么我们可以动态的为这个代理类添加一个接口吗,答案当然是可以。动态代理的高级用法请听下回分解,关注我,希望对您有帮助。

其实Autofac功能远不止这些,还有多租户、生命周期拦截等等,后面抽空分享给大家参考。


文章转载自码农游乐场,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论