[AOP系列]用Autofac与Costle.Core的Interceptor来实作AOP架构

前言

在AOP系列文章的第一篇有提到使用Autofac.Extras.DynamicProxy的Interceptor来实现AOP架构,本篇文章就来详细说明实作的方法。

Autofac 简介

Autofac是一个Ioc容器,Ioc为英文Inversion of Control控制反转的意思,控制反转是物件导向程式设计中的一种设计原则,可以用来减低电脑代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫「依赖寻找」(Dependency Lookup)。通过控制反转,物件在被建立的时候,由一个调控系统内所有物件的外界实体,将其所依赖的物件的参照传递(注入)给它。

以上说明参考维基

安装套件

要套用Autofac的Interceptor,主要需要安装三个套件分别是:

Autofac
Autofac.Extras.DynamicProxy
Castle.Core

Castle.Core主要功能是用来定义Interceptor的,而Autofac.Extras.DynamicProxy的功能是来将Interceptor与Autofac绑定在一起,让有在DI Container注册的服务(Service class)可以拥有AOP的功能,所以在实现AOP架构上,三者缺一不可。

设定与使用

从无到有设定拦截器Interceptor,一共会有三个步骤。

设计拦截器绑定拦截器服务Service挂载Interceptor

设定之后再来就是看结果,以下就让我慢慢说明,正篇开始啰!

设计拦截器

以例外处理为例,并使用NLog套件记录错误资讯,程式码如下。

/// <summary>/// 例外处理Interceptor/// </summary>public class ExceptionHandleInterceptor : IInterceptor{    /// <summary>    /// 例外处理内容    /// </summary>    /// <param name="invocation"></param>    public void Intercept(IInvocation invocation)    {        //初始化NLog        var logger = LogManager.GetLogger(invocation.GetType().FullName);        try        {            //执行方法            invocation.Proceed();        }        catch (Exception ex)        {            //若有例外发生,进行下列处理            //若回传值类型不为void            if (invocation.Method.ReturnType != typeof(void))            {                try                {                    //尝试传回初始值                    invocation.ReturnValue =                        Activator.CreateInstance(invocation.Method.ReturnType);                }                catch                {                    //失败则传回null                    invocation.ReturnValue = null;                }            }        }    }}

绑定拦截器(Interceptor)

首先在专案的AppStart资料夹新增一个AutofacConfig.cs,用来先设定Autofac,注册需要套用Autofac的服务(Service class),这边我会用一层Interface来让Service的Class继承,所以注册的时候是用Interface来注册,程式码如下。

public class AutofacConfig{public static IContainer container;public static void Bootstrap(){var builder = new ContainerBuilder();                //注册服务 TestService        //TestService继承于IService介面        //并且允许挂载拦截器builder.RegisterType<TestService>().As<IService>().EnableInterfaceInterceptors();                //注册例外处理Interceptorbuilder.RegisterType(typeof(ExceptionHandleInterceptor));container = builder.Build();}}

接着在专案的Startup.cs,执行AutofacConfig的设定

public partial class Startup{    public void Configuration(IAppBuilder app)    {        //执行Autofac的设定        AutofacConfig.Bootstrapper(app);    }}

服务Service挂载Interceptor

要在服务类别挂载Interceptor,有两种做法,第一种是直接在Service上面加入Intercept标籤,并且标注Interceptor的类型,如下。

做法A:在Service挂载Interceptor标籤

[Intercept(typeof(ExceptionLogInterceptor))]public class TestService : IService{}

第二种作法更全面也更简单一些,只要在刚刚的AutofacConfig绑定就好,就可以不用一个一个Service加上标籤,语法如下。

作法B:在AutofacConfig就绑定Interceptor

//注册Interface并绑定Interceptorbuilder.RegisterType<TestService>()   .As<IService>()   .EnableInterfaceInterceptors()   //以下两行绑定Interceptor   .InterceptedBy(typeof(ExceptionHandleInterceptor));

所以在Service上面的Intercept标籤就可以移除。

//这行可以拿掉[Intercept(typeof(ExceptionLogInterceptor))]

产生带有Interceptor的Service物件

绑定结束后,若要使用带有Interceptor的Service,记得不能直接new一个服务类别,要用以下语法,透过Autofac来产生服务类别,Interceptor才有效用。

 var service = AutofacConfig.container.Resolve<TService>(); service.Function();

执行Function后结果

在TestService内,加入一个TestFunctionWithException方法,来进行测试,变更后的程式码如下。

方法内容

public class TestService : IService{public int TestFunctionWithException(int x, int y)    {        //直接抛出错误讯息为 Test Error的例外        throw new Exception("Test Error.");    }}

Log纪录内容

2019-11-04 18:20:55.3275 | ERROR | RuntimeMethodInfo | 引动过程的目标传回例外状况。 | System.Reflection.TargetInvocationException: 引动过程的目标传回例外状况。 ---> System.Exception: Test Error.   于 .......

可以看到Test Error已经被自动记录到所设定的Log档案。

自订Interceptor

若是想要自己定义一个Interceptor,则新增类别并继承IInterceptor介面,範本如下,请记得invocation.Proceed()还是要写上去,让你的Interceptor处理完他的事情后,方法可以继续进行。

public class CustomInterceptor : IInterceptor{public void Intercept(IInvocation invocation){//what you want to do....//↓↓↓↓继续执行↓↓↓↓invocation.Proceed();}}

总结

本篇文章示範了使用Autofac的Interceptor功能来实作AOP,过程其实并不难,这么简单的几个步骤,就可以省去不少重工,所取得的效益十分的高,希望能够帮到各位伙伴们。在这边各位也许会有以下疑问,若不使用Autofac,是否也能实现AOP的框架?下篇即将介绍,敬请期待。

参考资源

[AOP系列]简单介绍AOP的概念
AOP 观念与术语
Autofac + Interceptors(AOP) 动态代理


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章