core 实现autofac
》》》 安装 如下工具包
安装之后 如出现 这种
》》》编写 AOP类
csharp
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");
}
}
}
}
csharp
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(拦截器))] 修饰接口实现的类,则只有此类的方法会拦截。
csharp
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}"); ;
}
}
}
csharp
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);
}
}
}
csharp
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
containerBuilder.RegisterModule<AutofacMoudleManager>();
});
忽略拦截
声明一个 特性 ,
csharp
if (invocation.Method.IsDefined(typeof(NeverInterceptAttribute), true))
{
Console.WriteLine("=======没有被拦截==========");
invocation.Proceed();
return;
}
接口代理 类代理
csharp
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
csharp
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>(); 接受 用 IZenServices
2. builder.RegisterType<MyZenServices>(); 接受 用 MyZenServices
3. builder.RegisterType<MyZenServices>().AsImplementedInterfaces(); 接受 用 IZenServices
builder.RegisterAssemblyTypes 注册程序集中符合条件的类型
csharp
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
csharp
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()
};
}
}
csharp
//支持AAOP扩展--接口扩展
builder.RegisterType<MyAresServices>().As<IAresServices>().EnableInterfaceInterceptors(
new ProxyGenerationOptions()
{
Selector = new ZenLogg()
});
AOP 实现缓存
》》》简易化
csharp
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)
{
//方法之前检查缓存的结果
//定义Key
string cacheKey = invocation.Method.Name;
//判断当前是否有缓存结果
if (_cacheDictionary.ContainsKey(cacheKey))
{
invocation.ReturnValue = _cacheDictionary[cacheKey];
}
else
{
//执行真实的方法
invocation.Proceed();
//方法之后保存缓存的结果
_cacheDictionary[cacheKey] = invocation.ReturnValue;
}
}