• ABP 配置全局数据过滤器


    可以不看下面内容,直接看这:https://www.cnblogs.com/MindSharing/p/11283914.html

    ================================

    ABP官方数据过滤的地址:https://aspnetboilerplate.com/Pages/Documents/Data-Filters

    中文可以看这个:https://aspnetboilerplate.com/Pages/Documents/Data-Filters

    看完后最大问题就是,自定义的数据过滤和UOW中事务是在一起的

    using (CurrentUnitOfWork.EnableFilter("PersonFilter"))
    {
        using(CurrentUnitOfWork.SetFilterParameter("PersonFilter", "personId", 42))
        {
            var phones = _phoneRepository.GetAllList();
            //...
        }
    }
    

    总不可能每次我写服务的时候,都在方法里面写一串这个代码吧,那这样也没方便多少

    所以可以考虑使用我方法来给过滤器全局设置一个值。

    我的应用场景是这样的,我的项目登录的时候会让用户选择一个专业,所有数据都是这个专业下的,什么建筑啊,结构啊

    为了实现这个筛选,先还是需要建立过滤器,在Core项目添加一个接口

        public interface IHasMajor
        {
            string Major { get; set; }
        }
    

     在EF项目中的DbContext.cs 中注册 过滤器

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);
    
    
                modelBuilder.Filter("MajorFilter", (IHasMajor entity, string major) => entity.Major == major, "");
    
            }
    

     在你需要筛选专业的实体里面实现这个接口

      [Table("DictionaryInfo")]
        public class DictionaryInfo : FullAuditedEntity, IHasMajor
        {
            public virtual int? ParentId { get; set; }
    
            public virtual string Value { get; set; }
    
            public virtual string Description { get; set; }
    
            public virtual DictionaryInfo ParentDictionaryInfo { get; set; }
    
            public virtual ICollection<DictionaryInfo> ChildDictionaryInfos { get; set; }
    
            public virtual string Major { get; set; }
        }
    

      好了下面就是关键的了,传统做法,我们就是在服务里面设置数据过滤的参数

            public async Task<GetDictionaryInfoOutput> GetAllDictionary()
            {
                using (CurrentUnitOfWork.SetFilterParameter(SysConsts.DataFilter.MajorFilter, SysConsts.DataFilter.MajorParameter, AbpSession.GetMajor()))
                {
                    List<DictionaryInfo> dictionaries = await _dictionaryInfoRepository.GetAllListAsync();
                    var result = new GetDictionaryInfoOutput
                    {
                        Dictionary = dictionaries.MapTo<List<DictionaryInfoDto>>()
                    };
                    return result;
                }
    
            }
    

      这种方式感觉很不优雅,改用拦截器来自动为每个服务注入 过滤器参数,

    ABP 官方对拦截器他也给了个例子,可以看这个

    https://www.codeproject.com/Articles/1080517/Aspect-Oriented-Programming-using-Interceptors-wit

    添加个一个拦截器,在应用层

        public class FilterInterceptor : IInterceptor
        {
            private readonly IAbpSession _abpSession;
    
            private readonly IUnitOfWork _unitOfWork;
    
            private readonly IUnitOfWorkManager _unitOfWorkManager;
    
            public FilterInterceptor(
                IUnitOfWork unitOfWork
                , IAbpSession abpSession
                , IUnitOfWorkManager unitOfWorkManager)
            {
                Logger = NullLogger.Instance;
                _unitOfWork = unitOfWork;
                _abpSession = abpSession;
                _unitOfWorkManager = unitOfWorkManager;
            }
    
            public ILogger Logger { get; set; }
    
            public void Intercept(IInvocation invocation)
            {
                string major = _abpSession.GetMajor();
    
                _unitOfWorkManager.Current.SetFilterParameter(SysConsts.DataFilter.MajorFilter, SysConsts.DataFilter.MajorParameter, major);
    
                //Executing the actual method
                invocation.Proceed();
            }
    
        }
    

      

    这里面有一个主意地方,拦截器请注入IUnitOfWorkManager ,而不是注入IUnitOfWork ,后者设置参数了,没效果

    然后再注册拦截器,在应用层添加一个文件

     public static class InterceptorRegistrar
        {
            public static void Initialize(IKernel kernel)
            {
                kernel.ComponentRegistered += Kernel_ComponentRegistered;
            }
    
            private static void Kernel_ComponentRegistered(string key, IHandler handler)
            {
                if (typeof(IApplicationService).IsAssignableFrom(handler.ComponentModel.Implementation))
                {
                    handler.ComponentModel.Interceptors.Add(new InterceptorReference(typeof(FilterInterceptor)));
                }
            }
        }
    

      在应用层的ApplicationModule.cs 文件里面的PreInitialize方法里面

    public override void PreInitialize()
            {
                InterceptorRegistrar.Initialize(IocManager.IocContainer.Kernel);
            }
    

      好这样就注册完了,可以试试服务层每个方法都能自动判断专业了,把服务里面手动设置筛选参数的地方都可以去掉了

         public async Task<GetDictionaryInfoOutput> GetAllDictionary()
            {
                //using (CurrentUnitOfWork.SetFilterParameter(SysConsts.DataFilter.MajorFilter, SysConsts.DataFilter.MajorParameter, AbpSession.GetMajor()))
                //{
                    List<DictionaryInfo> dictionaries = await _dictionaryInfoRepository.GetAllListAsync();
                    var result = new GetDictionaryInfoOutput
                    {
                        Dictionary = dictionaries.MapTo<List<DictionaryInfoDto>>()
                    };
                    return result;
                //}
    
            }
    

      

    专业的值是存在session里面的,如何把自己想要的值存到session 里面,可以参照这篇文章

    http://www.jianshu.com/p/930c10287e2a

  • 相关阅读:
    hdu 2881 Jack's struggle(DP)
    [置顶] DataGridView控件---绑定数据方法
    Computational Geometry Template_Polygon
    Max retries exceeded with url
    Linux /proc 的意义
    [置顶] 生成树协议介绍
    StringBuffer与StringBuilder的异同
    linux 下Eclipse for C/C++的不常见设置
    [Elasticsearch] 分布式搜索
    oracle递归函数
  • 原文地址:https://www.cnblogs.com/MindSharing/p/7576149.html
Copyright © 2020-2023  润新知