Ca_va
Autofac(依赖注入)的基本使用(Netcore2.X)
起:
在项目编程中,经常要记录整个项目的接口和调用情况。
如果只是控制器的话,直接使用过滤器或者是中间件即可。
或者也可以写切面来记录。
但是如果想看下与Service或者Repository层的调用情况,好像目前咱们只能在Service层或者Repository层去写日志记录了,
那样的话,不仅耦合性就会变的很高,不符合解耦的要求。
这个时候就需要用到AOP和Autofac的Castle结合的方法。
注:
1.本文项目基于上一章Autofac(依赖注入)的基本使用(Netcore2.X)
2.本文的重点并不是写日志,而是使用Autofac达成符合AOP的日志功能能。
基础:
所需nugut包:
Autofac.Extensions.DependencyInjection
Autofac.Extras.DynamicProxy
新建Log的AOP拦截器,并实现IInterceptor的Intercept方法
步骤如下:
1.继承IInterceptor
2.实例化IInterceptor唯一方法
3.记录被拦截方法信息的日志信息
4.继续执行当前方法
5.记录日志
/// <summary>
/// 拦截器LogAOP ,实现IInterceptor
/// 面向切面的日志使用
/// </summary>
public class LogAOP : IInterceptor{
/// <summary>
/// 实例化IInterceptor唯一方法
/// </summary>
/// <param name="invocation">包含被拦截的方法信息</param>
public void Intercept(IInvocation invocation) {
//记录被拦截方法信息的日志信息
var dataIntercept =
$"【当前执行方法】:{invocation.Method.Name}" +
$"【携带的参数有】:{string.Join(",", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray())} \r\n";
//在被拦截的方法执行完毕后 继续执行当前方法
invocation.Proceed();
//记录日志
WriteLine(dataIntercept);
}
}
Startup完成注入
步骤如下:
1.拦截器类注册
2.在对应注入中使用拦截器类
在这里插入图片描述
完整代码如下
#region Autofac注入
//获取项目路径
//var basePath = AppContext.BaseDirectory;
//var basePath = Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath;//这种方法可以取得路径
初始化AutoFac容器
var builder = new ContainerBuilder();
//日志拦截器的依赖注入
builder.RegisterType<LogAOP>();
#region 层级注入
#endregion
#region 普通注入,与netcore本身提供netcore一致
//builder.RegisterType<DemoServices>().As<IDemoServices>();
//builder.RegisterType<DemoRepository>().As<IDemoRepository>();
#endregion
#region Load模式,用于批量注入,此处需要在API层加载引用或者是将services层和repository的dll文件生成到api层
#region 加载引用注入
通过反射加载services程序集
//var assemblyServices = Assembly.Load("EptDemo2.Services");
指定已扫描程序集中的类型注册为提供所有其实现的接口
//builder.RegisterAssemblyTypes(assemblyServices).AsImplementedInterfaces();
通过反射加载repository
//var assemblyRepository = Assembly.Load("EpteDemo2.Repository");
//builder.RegisterAssemblyTypes(assemblyRepository).AsImplementedInterfaces();
#endregion
#region 加载dll文件注入
var basePath = AppContext.BaseDirectory;
var servicesDllFile = Path.Combine(basePath, "EptDemo2.Services.dll");
var assemblyServices = Assembly.LoadFile(servicesDllFile);
builder.RegisterAssemblyTypes(assemblyServices).AsImplementedInterfaces()
.EnableInterfaceInterceptors()引用Autofac.Extras.DynamicProxy;//对目标类型启用接口拦截。拦截器将被确定,通过在类或接口上截取属性, 或添加
.InterceptedBy(typeof(LogAOP));
var repositoryDllFile = Path.Combine(basePath, "EptDemo2.Repository.dll");
var assemblyRepository = Assembly.LoadFile(repositoryDllFile);
builder.RegisterAssemblyTypes(assemblyRepository).AsImplementedInterfaces();
#endregion
#endregion
//将services填充Autofac容器生成器
services.AddScoped<IDemoServices, DemoServices>();
//将services填充Autofac容器生成器
builder.Populate(services);
//使用已创建的组件登记创建新容器
var ApplicationContainer = builder.Build();
//第三方IOC接管 core内置DI容器
return new AutofacServiceProvider(ApplicationContainer);
#endregion
进阶
在上一步骤中,LogAOP类解惑的方法仅仅是针对同步,如果你的services是异步的,这里获取不到,所以代码需要更新
如下:
大概代码如下
/// <summary>
/// 实例化IInterceptor唯一方法
/// </summary>
/// <param name="invocation">包含被拦截的方法信息</param>
public void Intercept(IInvocation invocation)
{
//记录被拦截方法信息的日志信息
var dataIntercept =
//$"【当前操作用户】:{UserName}\r\n"+
$"【当前执行方法】:{invocation.Method.Name}" +
$"【携带的参数有】:{string.Join(",", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray())} \r\n";
try
{
//在被拦截的方法执行完毕后 继续执行当前方法
invocation.Proceed();
// 异步获取异常,先执行
if (IsAsyncMethod(invocation.Method)){
if (invocation.Method.ReturnType == typeof(Task)){
//异步方法日志
}else{
//同步方法日志
}
}
else//Task<TResult>
{//同步1
}
}
catch (Exception ex)//同步2
{
LogEx(ex, dataIntercept);
}
}
//判断方法是否为异步方法
private static bool IsAsyncMethod(MethodInfo method){
return (method.ReturnType == typeof(Task) ||
(method.ReturnType.IsGenericType && method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>))
);
}
private static bool IsAsyncMethod(MethodInfo method){
return (method.ReturnType == typeof(Task) ||
(method.ReturnType.IsGenericType && method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>))
);
————————————————
版权声明:本文为CSDN博主「Ca_va」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ca_va/article/details/106647047