Autofac没有拦截哪种类型的IInterceptor



我遇到了一个问题,那就是我试图使用Autofac记录拦截器。但logaspect没有进行拦截。事实上,aspectInterceptor选择器在单击添加方法时并没有进行拦截。所以你可以看到我的流程,

看到Jonathan的评论后,我想问问题可能是异步方法吗

Pogram.cs

public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(builder =>
{
builder.RegisterModule(new AutofacResolverModule());
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Trace);
});
}

//--------

AutofacResolverModule.cs

public class AutofacResolverModule : Module
{
public AutofacResolverModule()
{

}
protected override void Load(ContainerBuilder builder)
{
builder.RegisterGeneric(typeof(Repository<,>)).As(typeof(IRepository<,>));
builder.RegisterGeneric(typeof(BaseService<,,>)).As(typeof(IBaseService<,,>));
builder.RegisterType<FileLogger>();

#region AutofacInterceptorHelper
var assembly = Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces()
.EnableInterfaceInterceptors(new ProxyGenerationOptions()
{
Selector = new AspectInterceptorSelector()
}).SingleInstance().InstancePerDependency();
#endregion
}
}

//---------

AspectInterceptorSelector.cs

public class AspectInterceptorSelector: IInterceptorSelector
{
public IInterceptor[] SelectInterceptors(Type type, MethodInfo method, IInterceptor[] interceptors)
{
var classAttributes = type.GetCustomAttributes<MethodInterceptorBaseAttribute>(true).ToList();
var methodAttributes =
type.GetMethod(method.Name)?.GetCustomAttributes<MethodInterceptorBaseAttribute>(true);
if (methodAttributes != null)
{
classAttributes.AddRange(methodAttributes);
}
//classAttributes.Add(new LogAspect(typeof(FileLogger)));
return classAttributes.OrderBy(x => x.Priority).ToArray();
}
}

BaseService.cs

This class is generic base class and my purpose is all post methods logged into .txt file , is there any problem to use this log aspect into a generic class ?     
public class BaseService<TEntity, TPrimaryKey, TEntityDto> : IBaseService<TEntity, TPrimaryKey, TEntityDto> where TEntity : BaseEntity<TPrimaryKey>, new()
where TEntityDto : IDto
{
private readonly IRepository<TEntity, TPrimaryKey> _repository;
private readonly IMapper _mapper;
public BaseService(IRepository<TEntity, TPrimaryKey> repository, IMapper mapper)
{
_repository = repository;
_mapper = mapper;
}

[LogAspect(typeof(FileLogger))]
public async Task<IResult> Add(TEntityDto entityDto)
{
var entity = _mapper.Map<TEntity>(entityDto);
var result = await _repository.Add(entity);
return result == null ? new Result(false, ErrorMessages.CreateMessage) : new Result(true, SuccessMessages.CreateMessage, result.Id);

}

public async Task<IResult> Find(Expression<Func<TEntity, bool>> predicate)
{
var result = await _repository.Find(predicate);
return result == null ? new Result(true, ErrorMessages.GetMessage) : new Result(true, _mapper.Map<List<ExampleDto>>(result));
}
public async Task<IResult> GetAll(Expression<Func<TEntity, bool>> predicate = null)
{
var result = predicate == null ? await _repository.GetAll() : await _repository.GetAll(predicate);
return result == null ? new Result(true, ErrorMessages.GetMessage) : new Result(true, _mapper.Map<List<ExampleDto>>(result));
}
public async Task<IResult> HardDelete(TPrimaryKey Id)
{
var entity = await _repository.Find(x => x.Id.Equals(Id));
var result = await _repository.HardDelete(entity);
return result == 0 ? new Result(false, ErrorMessages.DeleteMessage) : new Result(true, SuccessMessages.DeleteMessage);
}
public async Task<IResult> Delete(TPrimaryKey Id)
{
var entity = await _repository.Find(x => x.Id.Equals(Id));
var result = await _repository.Delete(entity);
return result == 0 ? new Result(false, ErrorMessages.DeleteMessage) : new Result(true, SuccessMessages.DeleteMessage);
}
public async Task<IResult> Update(TEntityDto entityDto)
{
var entity = _mapper.Map<TEntity>(entityDto);
var result = await _repository.Update(entity);
return result == null ? new Result(false, ErrorMessages.UpdateMessage) : new Result(true, SuccessMessages.UpdateMessage, result.Id);
}
}

LogAspect.cs

public class LogAspect : MethodInterceptor
{
private readonly LoggerServiceBase _loggerServiceBase;
private readonly IHttpContextAccessor _httpContextAccessor;
public LogAspect(Type loggerService)
{
if (loggerService.BaseType != typeof(LoggerServiceBase))
{
throw new ArgumentException("Wrong Type");
}
_loggerServiceBase = (LoggerServiceBase)ServiceTool.ServiceProvider.GetService(loggerService);
_httpContextAccessor = ServiceTool.ServiceProvider.GetService<IHttpContextAccessor>();
}
protected override void OnBefore(IInvocation invocation)
{
_loggerServiceBase?.Info(GetLogDetail(invocation));
}
private string GetLogDetail(IInvocation invocation)
{
var logParameters = new List<LogParameters>();
for (var i = 0; i < invocation.Arguments.Length; i++)
{
logParameters.Add(new LogParameters
{
Name = invocation.GetConcreteMethod().GetParameters()[i].Name,
Value = invocation.Arguments[i],
Type = invocation.Arguments[i].GetType().Name,
});
}
var logDetail = new LogDetails
{
MethodName = invocation.Method.Name,
Parameters = logParameters,
User = (_httpContextAccessor.HttpContext == null ||
_httpContextAccessor.HttpContext.User.Identity.Name == null)
? "?"
: _httpContextAccessor.HttpContext.User.Identity.Name
};
return JsonConvert.SerializeObject(logDetail);
}
}

MethodInterceptor.cs

public abstract class MethodInterceptor: MethodInterceptorBaseAttribute
{
public override void Intercept(IInvocation invocation)
{
var isSuccess = true;
OnBefore(invocation);
try
{
invocation.Proceed();
var result = invocation.ReturnValue as Task;
result?.Wait();
}
catch (Exception e)
{
isSuccess = false;
OnException(invocation, e);
throw;
}
finally
{
if (isSuccess)
{
OnSuccess(invocation);
}
}
OnAfter(invocation);
}
protected virtual void OnBefore(IInvocation invocation)
{
}
protected virtual void OnAfter(IInvocation invocation)
{
}
protected virtual void OnException(IInvocation invocation, Exception e)
{
}
protected virtual void OnSuccess(IInvocation invocation)
{
}
}

MethodInterceptorBaseAttribute.cs

[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method , AllowMultiple = true,Inherited = true)]
public abstract class MethodInterceptorBaseAttribute:Attribute, IInterceptor
{
public int Priority { get; set; }
public virtual void Intercept(IInvocation invocation)
{

}
}

所以我几乎一个月都找不到这个解决方案了,有什么想法吗?

Tarık。在我看来,您的错误是没有将泛型类型注册到程序集配置中。您应该在AutofacResolverModule.cs 中注册泛型类型

builder.RegisterAssemblyOpenGenericTypes(assembly).AsImplementedInterfaces()
.EnableInterfaceInterceptors(new ProxyGenerationOptions()
{
Selector = new AspectInterceptorSelector()
}).SingleInstance().InstancePerDependency();

相关内容

  • 没有找到相关文章

最新更新