资料
core 实现autofac
》》》 安装 如下工具包
安装之后 如出现 这种
》》》编写 AOP类
using Castle.DynamicProxy;
using System.Diagnostics;namespace Web01.AOP
{/// <summary>/// 日志记录/// </summary>public class LoggingInterceptor : IInterceptor{public void Intercept(IInvocation invocation){//被调用的方法名var methodName = invocation.Method.Name;//被调方法所属的类名var className = invocation.TargetType.Name;//被调用方法的参数列表var arguments = string.Join(", ", invocation.Arguments);Console.WriteLine($"方法执行之前:{className}-{methodName}-{arguments}");var stopwatch = Stopwatch.StartNew();try{//执行原始方法的逻辑 就是被调用的方法invocation.Proceed();}catch (Exception ex){//输出方法执行完成的日志信息和执行时间Console.WriteLine($"方法执行异常: {className}.{methodName}");Console.WriteLine($"异常信息: {ex}");throw;}finally{stopwatch.Stop();Console.WriteLine($"方法执行之后: {className}.{methodName}");Console.WriteLine($"方法执行时间:{stopwatch.ElapsedMilliseconds} ms");}}}
}
using Castle.DynamicProxy;
using System.Diagnostics;namespace Web01.AOP
{/// <summary>/// 事务管理拦截器/// </summary>public class TransactionInterceptor : IInterceptor{public void Intercept(IInvocation invocation){var methodName = invocation.Method.Name;var arguments = string.Join(", ", invocation.Arguments);var className = invocation.TargetType.Name;Console.WriteLine($"Before exectiong method [方法执行之前]:{className}-{methodName}-{arguments}");var stopwatch= Stopwatch.StartNew();try{invocation.Proceed();}catch (Exception ex){stopwatch.Stop();Console.WriteLine($"After executing method[ 方法执行之后]:{className}-{methodName}");Console.WriteLine($"Execution time[方法执行的时间]:{stopwatch.ElapsedMilliseconds} ms");throw;}}}
}
》》》接口 添加拦截器
[Intercept(typeof(拦截器))] 修饰接口,则实现接口的所有类 都会拦截,除非打标签【特性】
[Intercept(typeof(拦截器))] 修饰接口实现的类,则只有此类的方法会拦截。
namespace Web01.Comm
{public class MyAresServices : IAresServices{public void Print(){Console.WriteLine( $"MyAresServices--Print 触发" ); ;}public void Print(string name, int age){Console.WriteLine($"MyAresServices--Print 参数为:姓名:{name}--年龄:{age}"); ;}}
}
using Autofac;
using Autofac.Extras.DynamicProxy;
using Web01.AOP;namespace Web01.Comm
{/// <summary>/// Moudle 是Autofac命名空间下面的 /// </summary>public class AutofacMoudleManager:Module{/// <summary>/// 重写Autofac管道Load 方法,load方法里面是注册注入的/// </summary>/// <param name="builder"></param>protected override void Load(ContainerBuilder builder){#region 注册 AOP//注册日志记录拦截器builder.RegisterType<LoggingInterceptor>();//注册性能拦截器builder.RegisterType<PerformanceInterceptor>();//注册事务管理器拦截器builder.RegisterType<TransactionInterceptor>();#endregion//builder.RegisterType<MyAresServices>().As<IAresServices>();builder.RegisterType<MyZenServices>().As<IZenServices>().InstancePerDependency().EnableInterfaceInterceptors(); builder.RegisterType<MyAresServices>().As<IAresServices>().InstancePerDependency().EnableInterfaceInterceptors(); // .EnableInterfaceInterceptors() // .AsImplementedInterfaces()// .InstancePerLifetimeScope()// .EnableInterfaceInterceptors()// .InterceptedBy(typeof(LoggingInterceptor), typeof(PerformanceInterceptor), typeof(TransactionInterceptor));;//builder.RegisterType<MyZenServices>().As<IZenServices>();//通.InterceptedBy(typeof(LoggingInterceptor), typeof(PerformanceInterceptor), typeof(TransactionInterceptor));过反射机制实现批量注册服务和拦截器//builder.RegisterAssemblyTypes(Assembly.Load("Web01"))// .Where(a => a.Name.EndsWith("Services"))// .AsImplementedInterfaces()// .InstancePerLifetimeScope()// .EnableInterfaceInterceptors()// .InterceptedBy(typeof(LoggingInterceptor), typeof(PerformanceInterceptor), typeof(TransactionInterceptor));//.AsImplementedInterfaces():注册的服务的生命周期是默认的 Transient 生命周期//.InstancePerLifetimeScope():每个请求(即每个 HTTP 请求)创建一个实例,并在整个请求期间重用//.SingleInstance():在整个应用程序生命周期中只创建一个实例,并在每次解析时重用//.InstancePerDependency():每次解析时都创建一个新的实例//builder.RegisterAssemblyTypes(Assembly.Load("xxxxx"))// .Where(a => a.Name.EndsWith("Services"))// .AsImplementedInterfaces()// .SingleInstance();base.Load(builder);}}
}
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()).ConfigureContainer<ContainerBuilder>(containerBuilder =>{containerBuilder.RegisterModule<AutofacMoudleManager>();});
忽略拦截
声明一个 特性 ,
if (invocation.Method.IsDefined(typeof(NeverInterceptAttribute), true)){Console.WriteLine("=======没有被拦截==========");invocation.Proceed();return;}
源码
接口代理 类代理
using Autofac;
using Autofac.Extras.DynamicProxy;
using WebApplication2.AOP;namespace WebApplication2.Coms
{public class AutofacMoudleManager:Module{/// <summary>/// 重写Autofac管道Load 方法,load方法里面是注册注入的/// </summary>/// <param name="builder"></param>protected override void Load(ContainerBuilder builder){#region 注册 AOP 把拦截器注册到 autofac 容器中//注册日志记录拦截器//builder.RegisterType<LoggingInterceptor>();// 命名注入//builder.Register<LoggingInterceptor>(c => new LoggingInterceptor()).Named<IInterceptor>("log-record");// 类型注入//builder.Register<LoggingInterceptor>(c=>new LoggingInterceptor());builder.RegisterType<LoggingInterceptor>();//builder.RegisterType(typeof(LoggingInterceptor));//注册性能拦截器builder.RegisterType<PerformanceInterceptor>();//注册事务管理器拦截器builder.RegisterType<TransactionInterceptor>();#endregion#region 注册服务 builder.RegisterType<MyZenServices>().As<IZenServices>();// EnableInterfaceInterceptors方法会动态创建一个接口代理// EnableClassInterceptors方法会创建一个目标类的子类代理类,这里需要注意的是只会拦截虚方法,重写方法//-InstancePerLifetimeScope 每个请求(即每个 HTTP 请求)创建一个实例,并在整个请求期间重用//.AsImplementedInterfaces():注册的服务的生命周期是默认的 Transient 生命周期//.SingleInstance():在整个应用程序生命周期中只创建一个实例,并在每次解析时重用//.InstancePerDependency():每次解析时都创建一个新的实例// 命名注册//builder.RegisterType<MyAresServices>().Named<IAresServices>(typeof(MyAresServices).Name).EnableClassInterceptors();//=================启用接口代理拦截==================== //方式一:需要在接口、实现的类 添加特性 [Intercept(typeof(xxx拦截器))] ///比如 [Intercept(typeof(LoggingInterceptor))]/// 接口加 Intercept 特性,实现接口的类 全部生效/// 实现类 加 Intercept 特性 ,只有此类 生效//builder.RegisterType<MyAresServices>().As<IAresServices>() // .EnableInterfaceInterceptors();// //方式二:在 注册服务 类型到容器的时候动态注入拦截器(去掉接口、实现的类型上的特性 Intercept) 不要添加特性Intercept// InterceptedBy 支持多个拦截器builder.RegisterType<MyAresServices>().As<IAresServices>().InterceptedBy(typeof(LoggingInterceptor), typeof(PerformanceInterceptor)).EnableInterfaceInterceptors();//================= 启用 类代理拦截=== 只会拦截虚方法==================// 方式一 添加特性 [Intercept(typeof(xxx拦截器))] //builder.RegisterType<Student>().EnableClassInterceptors();// 方式二 不需要添加 特性Intercept builder.RegisterType<Student>().InterceptedBy(typeof(LoggingInterceptor)).EnableClassInterceptors();#endregion// 程序集注册//builder.RegisterAssemblyTypes(Assembly.Load("Web01"))// .Where(a => a.Name.EndsWith("Services"))// .AsImplementedInterfaces()// .InstancePerLifetimeScope()// .EnableInterfaceInterceptors()// .InterceptedBy(typeof(LoggingInterceptor), typeof(PerformanceInterceptor), typeof(TransactionInterceptor));base.Load(builder);}}
}
Autofac 三种生命周期 InstancePerLifetimeScope、SingleInstance、InstancePerDependency
builder.RegisterType<MyZenServices>().As<IZenServices>()//.EnableInterfaceInterceptors方法会动态创建一个接口代理// .EnableClassInterceptors方法会创建一个目标类的子类代理类,这里需要注意的是只会拦截虚方法,重写方法//-InstancePerLifetimeScope 每个请求(即每个 HTTP 请求)创建一个实例,并在整个请求期间重用//.AsImplementedInterfaces():注册的服务的生命周期是默认的 Transient 生命周期//.SingleInstance():在整个应用程序生命周期中只创建一个实例,并在每次解析时重用//.InstancePerDependency():每次解析时都创建一个新的实例
InstancePerLifetimeScope:
同一个Lifetime生成的对象是同一个实例 (每个请求(即每个 HTTP 请求)创建一个实例,并在整个请求期间重用)
SingleInstance:
单例模式,每次调用,都会使用同一个实例化的对象;每次都用同一个对象;
在整个应用程序生命周期中只创建一个实例,并在每次解析时重用
InstancePerDependency:
默认模式,每次调用,都会重新实例化对象;每次请求都创建一个新的对象
每次解析时都创建一个新的实例
AsImplementedInterfaces()
AsImplementedInterfaces() 是以接口方式进行注入,注入这些类的所有的公共接口作为服务(除了释放资源)
AsImplementedInterfaces注册的服务的生命周期是默认的 Transient 生命周期
builder.RegisterType().AsImplementedInterfaces(); 使用时用IA,会返回一个A的实例,即将自身的实例进行注入
1. builder.RegisterType<MyZenServices>().As<IZenServices>(); 接受 用 IZenServices2. builder.RegisterType<MyZenServices>(); 接受 用 MyZenServices3. builder.RegisterType<MyZenServices>().AsImplementedInterfaces(); 接受 用 IZenServices
builder.RegisterAssemblyTypes 注册程序集中符合条件的类型
Assembly assembly = Assembly.Load(assemblyName);//Assembly assembly = this.GetType().GetTypeInfo().Assembly;builder.RegisterAssemblyTypes(assembly).Where(type => !type.IsInterface && !type.IsSealed && !type.IsAbstract && type.Name.EndsWith("BLL", StringComparison.OrdinalIgnoreCase)).AsImplementedInterfaces().InstancePerLifetimeScope().EnableInterfaceInterceptors().InterceptedBy(typeof(LogInterceptor));
IInterceptorSelector
》》》没有没有 InterceptedBy 则需要加特性,但InterceptedBy 如果太多不利于管理,所以 IInterceptorSelector
public class ZenLogg : IInterceptorSelector
{/// <summary>/// 让我们选择使用那个IInterceptor/// </summary>/// <param name="type"></param>/// <param name="method"></param>/// <param name="interceptors"></param>/// <returns></returns>/// <exception cref="NotImplementedException"></exception>public IInterceptor[] SelectInterceptors(Type type, MethodInfo method, IInterceptor[] interceptors){return new IInterceptor[] {new LoggingInterceptor(),new PerformanceInterceptor(),new TransactionInterceptor()};}
}
//支持AAOP扩展--接口扩展builder.RegisterType<MyAresServices>().As<IAresServices>().EnableInterfaceInterceptors(new ProxyGenerationOptions(){Selector = new ZenLogg()});
AOP 实现缓存
》》》简易化
public class CusotmCacheInterceptor : IInterceptor{/// <summary>/// 定义构造函数/// </summary>private readonly ILogger<CusotmCacheInterceptor> _ILogger;/// <summary>/// 初始化构造函数/// </summary>/// <param name="logger"></param>public CusotmCacheInterceptor(ILogger<CusotmCacheInterceptor> logger){this._ILogger = logger;}//定义字典private static Dictionary<string, object> _cacheDictionary = new Dictionary<string, object>();/// <summary>/// 切入者逻辑/// </summary>/// <param name="invocation"></param>public void Intercept(IInvocation invocation){//方法之前检查缓存的结果//定义Keystring cacheKey = invocation.Method.Name;//判断当前是否有缓存结果if (_cacheDictionary.ContainsKey(cacheKey)){invocation.ReturnValue = _cacheDictionary[cacheKey];}else{//执行真实的方法invocation.Proceed();//方法之后保存缓存的结果_cacheDictionary[cacheKey] = invocation.ReturnValue;}}
资料