0

我有一个问题,我正在尝试使用 Autofac 记录拦截器。但是 logaspect 没有拦截。确实 aspectInterceptor 选择器在单击添加方法时没有拦截。所以你可以看到我的流程,

看到乔纳森的评论后,我想问一下问题可能是 asyc 方法吗?

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);
    }
}

方法拦截器.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)
        {
            
        }
    }

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

4

0 回答 0