基于ABP扩展类似审计(IHasCreationTime)功能

来源:转载

 

前言

因为公司项目都是基于abp这套框架来实现功能,最近项目在调整所以我们想自己实现Module-Zero相应的功能,毕竟Module-Zero 是收费的(你懂的)今天就是实现类似审计(IHasCreationTime等)自动添加创建人,创建时间功能(子帐号概念)

思路

  1. 首先想到的是重写abp关于仓储的新增方法,代码确实很多,自身又对abp的源码没有太多的研究,放弃

  2. 每次实例化实体的时候手动给所属帐号Id手动赋值,麻烦,放弃

  3. 参考abp关于IHasCreationTime审计功能自动添加创建用户Id的思路,在继承AbpDbContext(数据上下文)中类中重写AbpDbContext定义的ObjectStateManager_ObjectStateManagerChanged这个方法。然后再声明一个受保护的SetChildAcountProperties方法用户给自账号相应字段赋值。

问题

  1. 本来想直接在XXXXXXDbContext:AbpDbContext类中声明一个基于IAbpsession扩展的Abpsession属性的,结果发现还不能这样写,关于拓展abpsession的文章请看连接博客园【圣杰】的ABP入门系列(10)——扩展AbpSession,后面采用了其他方式进行获取相应的值,下面的代码中会说明。请教各位大神为何在XXXXXXDbContext不能像下面这样获取拓展之后的AbpSession值

    public new IAbpSessionExtensions AbpSession { get; set; } 
  2. 本身我们子帐号就是获取abpsession的UserId,我就想能不能在获取了abpsession.UserId之后在数据上下文中使用Users.Find(AbpSession.UserId)方法来查找我需要的其他字段,发现可以但是引发了一个其他地方的问题代码如下,提示“未将对象设置到引用的错误”
    _xxxxxxRepository.Insert(model);

实现

  • 重写XXXXXXDbContext:AbpDbContext类中的ObjectStateManager_ObjectStateManagerChanged
 1 protected override void ObjectStateManager_ObjectStateManagerChanged(object sender, CollectionChangeEventArgs e) 2 { 3 var contextAdapter = (IObjectContextAdapter)this; 4 if (e.Action != CollectionChangeAction.Add) 5 { 6 return; 7 } 8 9 var entry = contextAdapter.ObjectContext.ObjectStateManager.GetObjectStateEntry(e.Element);10 switch (entry.State)11 {12 case EntityState.Added:13 CheckAndSetId(entry.Entity);14 CheckAndSetMustHaveTenantIdProperty(entry.Entity);15 SetCreationAuditProperties(entry.Entity, GetAuditUserId());16 SetChildAcountProperties(entry.Entity);17 break;18 }19 }
  • SetChildAcountProperties方法如下:
 /// <summary> /// 设置子帐号属性字段值 /// </summary> /// <param name="entityAsObj">实体对象设置成Obj</param> protected void SetChildAcountProperties(object entityAsObj) { var entityWithChildAccount = entityAsObj as IChildAccount; if (entityWithChildAccount == null) { return; } var entity = entityAsObj.As<IChildAccount>(); if (!string.IsNullOrWhiteSpace(GetClaimValue(ClaimTypes.NameIdentifier))) entity.BelongUserId = Convert.ToInt64(GetClaimValue(ClaimTypes.NameIdentifier)); if (!string.IsNullOrWhiteSpace(GetClaimValue(ClaimTypeExtensions.LayerCode))) entity.UserLayerCode = GetClaimValue(ClaimTypeExtensions.LayerCode); }
  • 其中GetClaimValue方法就是没有在拓展abpsession属性中拿取到才使用的折中的办法,其实按照博客园大神说的abpsession拓展的核心还是从用户申明(Claims)中获取,代码如下:
 /// <summary> /// 获取申明值 /// </summary> /// <returns></returns> protected string GetClaimValue(string claimType) { var claimsPrincipal = DefaultPrincipalAccessor.Instance.Principal; var claim = claimsPrincipal?.Claims.FirstOrDefault(c => c.Type == claimType); return string.IsNullOrEmpty(claim?.Value) ? null : claim.Value; }
  • 至此已经完成了代码的功能,有图有真相

总结

  文章中是自己的理解,仅供参考abp路还很长,需要继续努力学习,很多很好的思想,思路都需要借鉴!!!

 

延伸

还有一个“”姿势”点就是可以做数据筛选,博客园中有很多关于自定义拓展abpDataFilter的文章都可以关注一下,期待下一篇更新吧,哈哈~

参考

文章中关于abpsession拓展的思路是来自:

作者:圣杰

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

來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

分享给朋友:
您可能感兴趣的文章:
随机阅读: