业务型网站使用过程中,消息通知是一个不可或缺的功能,采用站内通知、短信通知、邮件通知、微信通知等等各种方式都有,ABP框架对这部分工作已经封装的很好了,站在巨人的肩膀上,一览全貌,带来的就是心情舒畅。

  ABP官网地址:https://aspnetboilerplate.com/

一、明确概念及设计

  一次完整的消息发送/接收过程中,会存在几个必要的点,也正如同现实生活中的场景,有人发送,有人接收,发送的消息本身也有类型。

  

1、消息类型定义

  在ABP中已经提供了消息类型定义的相关类,但是需要我们去实现,在领域层新建一个Notifications文件夹并添加一个定义常用消息类型名称的静态类如AppNotificationNames(名称可随意),在其中开始定义消息类型名称。

/// <summary>
/// 设置应用程序中常用通知唯一的名称常量
/// </summary>
public static class AppNotificationNames
{
#region 新的任务
public const string NewTask = "App.NewTask";
#endregion #region 简单消息
public const string SimpleMessage = "App.SimpleMessage";
#endregion
}

  其次,开始消息类型定义,新建一个NotificationProvider的类,完成消息类型定义,管理消息类型时,可以针对消息设置权限,这样方便不同的角色拥有不同的消息通知。

/// <summary>
/// 消息类型定义
/// </summary>
public class AppNotificationProvider : NotificationProvider
{
/// <summary>
/// 设置消息类型
/// </summary>
/// <param name="context"></param>
public override void SetNotifications(INotificationDefinitionContext context)
{
#region 任务提醒
context.Manager.Add(
new NotificationDefinition(
AppNotificationNames.NewTask,
displayName: L("NewTask"),
permissionDependency: new SimplePermissionDependency(PermissionNames.Pages_TaskManage)
)
);
#endregion
} private static ILocalizableString L(string name)
{
return new LocalizableString(name, SurroundConsts.LocalizationSourceName);
}
}

  最后在领域层的Module.PreInitialize()中完成加入。

//通知定义
Configuration.Notifications.Providers.Add<AppNotificationProvider>();

2、消息订阅方式

  对于消息订阅环节,是存在两种情形的,第一种,发送方发出的消息,可以指定所有订阅了的人员接收,比如,只有拥有任务管理权限的人才会接收到新的任务下发的通知;第二种就是指定到具体人员接收,比如文件上传完毕的消息通知是通知到负责文件上传的人。

   

  消息订阅的管理,在ABP框架中已经封装好了,我们可以通过构造函数注入直接使用,通过获取系统内的提前定义的所有消息类型,我们可以在界面上完成订阅工作,为当前用户订阅在他角色权限内的消息通知及无权限限制的消息通知等。

private readonly INotificationDefinitionManager _notificationDefinitionManager;
private readonly INotificationSubscriptionManager _notificationSubscriptionManager; public NotificationAppService(
INotificationDefinitionManager notificationDefinitionManager,
INotificationSubscriptionManager notificationSubscriptionManager)
{
_notificationDefinitionManager = notificationDefinitionManager;
_notificationSubscriptionManager = notificationSubscriptionManager;
}

3、消息发布方式

  

  消息发布时,可以是嵌入在其它操作中,比如制定完成一个新的任务后,发送消息给相关人员,或是在文件上传完毕后,发送给文件上传人员,也可以是定时任务中,指定时间点发送消息,对于这部分来讲,在领域层建立一个消息通知的类,来负责处理消息通知,而具体实现消息通知的过程ABP框架中已经实现了,如同消息订阅一样,只需要在构造函数中注入即可,其次定义具体的消息发送方法,使得具体操作结束后调用具体的消息发送来发送消息。

/// <summary>
/// 消息通知发布实例
/// </summary>
public class AppNotifier : DomainService, IAppNotifier
{
#region 初始化
private readonly INotificationPublisher _notificationPublisher; public AppNotifier(INotificationPublisher notificationPublisher)
{
_notificationPublisher = notificationPublisher;
}
#endregion #region 消息发送
public async Task SendMessageAsync(UserIdentifier user, string message, NotificationSeverity severity = NotificationSeverity.Info)
{
await _notificationPublisher.PublishAsync(
AppNotificationNames.SimpleMessage,
new MessageNotificationData(message),
severity: severity,
userIds: new[] { user }
);
}
#endregion #region 任务提醒
public async Task NewTaskAsync(string message, NotificationSeverity severity = NotificationSeverity.Info)
{
await PublishMessage(AppNotificationNames.NewTask, message);
}
#endregion #region 辅助方法
private async Task PublishMessage(string appNotificationName, string message)
{
await _notificationPublisher.PublishAsync(appNotificationName, new MessageNotificationData(message));
}
#endregion
}

二、完成用户订阅消息

  在MVC层,在用户控制器中完成对消息通知设置,消息本身是独立的,只应有了用户才活跃起来,因此把消息的设定挂钩在用户身上,应该算是合理的,并同时完成页面的设计。

/// <summary>
/// 通知设置
/// </summary>
/// <returns></returns>
public async Task<ActionResult> NotificationSetting()
{
var notificationSettings = await _notificationAppService.GetNotificationSettings();
return View(notificationSettings);
} /// <summary>
/// 更新通知订阅
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<JsonResult> UpdateNotificationSetting([FromBody]UpdateNotificationSettingsInput input)
{
await _notificationAppService.UpdateNotificationSettings(input);
return Json(new ResponseParamViewModel("通知设置已更新"));
}

  页面设计只需要对提前在领域层中定义好的消息类型展示出来即可,用户自主勾选哪些想要接收的消息提示。

  

三、发布消息通知用户

  在指定操作完毕,可以调用消息服务来推送消息到目标接收人员,此处,更改了原先数据字典创建处的代码,当创建数据字典成功后,给与一个消息提示来模拟发布消息通知用户的过程。

var existedDataDictionary = await _dataDictionaryRepository.GetAll().Where(d => d.TypeName == input.DataDictionary.TypeName).FirstOrDefaultAsync();

if (existedDataDictionary != null)
{
throw new UserFriendlyException(L("该字典类型已存在,无法添加"));
} var dataDictionary = ObjectMapper.Map<DataDictionary>(input.DataDictionary);
await _dataDictionaryRepository.InsertAsync(dataDictionary); //模拟测试消息通知
await _appNotifier.NewTaskAsync("字典类型已完成添加,可以开始使用了");

  该消息触发的前提是,需要订阅该消息,不然有人发,无人收,总是很难为情。因此提前在通知设置中开启类型为“新的任务”的开关。

  

  对于消息发送到了浏览器中呈现,这个过程采用了SignalR,ABP框架也完成了前后端的消息通知,因此可以直接使用即可。

  至此,站内消息通知的设计完毕,对于业务需求中可能面对的更为丰富的功能就得花更多时间来完成了。 

  代码地址:https://gitee.com/530521314/Partner.Surround.git

2019-07-27,望技术有成后能回来看见自己的脚步

X-Admin&ABP框架开发-消息通知的更多相关文章

  1. iOS开发-消息通知机制(NSNotification和NSNotificationCenter)

    iOS中委托模式和消息机制基本上开发中用到的比较多,一般最开始页面传值通过委托实现的比较多,类之间的传值用到的比较多,不过委托相对来说只能是一对一,比如说页面A跳转到页面B,页面的B的值改变要映射到页 ...

  2. X-Admin&ABP框架开发-系统日志

    网站正常运行中有时出现异常在所难免,查看系统运行日志分析问题并能够根据错误信息快速解决问题尤为重要,ABP对于系统运行日志这块已经做了很好的处理,默认采用的Log4Net已经足够满足开发过程中的需要了 ...

  3. X-Admin&ABP框架开发-版本管理

    多租户系统中,针对于不同租户开放不同功能,或是按照不同功能进行收费管理,需要从宿主本身去管理租户的版本信息,如同酒店人员对不同房间收取不同费用,依据房间内部设施,房间大小等设置不同收费标准.Abp系统 ...

  4. X-Admin&ABP框架开发-设置管理

    在网站开发中,设置是不可缺少的一环,如用户设置.系统设置.甚至是租户设置等.ABP对于设置的管理已经做了很好的处理,我们可以借助巨人的力量来完成我们的冒险. ABP官网地址:https://aspne ...

  5. X-Admin&ABP框架开发-代码生成器

    在日常开发中,有时会遇到一些相似的代码,甚至是只要CV一次,改几个名称,就可以实现功能了,而且总归起来,都可以由一些公用的页面更改而来,因此,结合我日常开发中使用到的页面,封装一个适合自己的代码生成器 ...

  6. X-Admin&ABP框架开发-RBAC

    在业务系统需求规划过程中,通常对于诸如组织机构.用户和角色等这种基础功能,通常是将这部分功能规划到通用子域中,这也说明了,对于这部分功能来讲,是系统的基石,整个业务体系是建立于这部分基石之上的,当然, ...

  7. X-Admin&ABP框架开发-数据字典

    在业务型的系统开发中,我们需要维护各种个样的类型,比如客户类型.客户行业.商品类型等等,这些类型往往信息量不多,并且相似度极高,如果采用一类型一表去设计,将会造成极大的工作量,通过将这部分类型的信息进 ...

  8. X-Admin&ABP框架开发-租户管理

    软件即服务概念的推动,定制化到通用化的发展,用一套代码完成适应不同企业的需求,利用多租户技术可以去做到这一点.ABP里提供了多租户这一概念并且也在Zero模块中实现了这一概念. 一.多租户的概念 单部 ...

  9. ABP框架个人开发实战(1)_环境搭建

    前言 之前关注ABP框架有一阵子了,一直没有潜下心来实际研究一下.最近想自己建站,以后有自己的功能开发项目,可以在自己的站点上开发,并一步步的完善,所以找个比较好用的框架迫在眉睫,选来选去,决定用AB ...

随机推荐

  1. python中的内置函数(bytearray)

    返回一个新的字节数组.bytearray类是range 0 < = x < 256的一个可变序列.它有大多数可变序列的常用方法,在可变序列类型中描述,以及大多数字节类型的方法,参见字节和B ...

  2. 开源|性能优化利器:数据库审核平台Themis的选型与实践

    作者:韩锋 出处:DBAplus社群分享:来源:宜信技术学院 Themis开源地址:https://github.com/CreditEaseDBA 一.面临的挑战 1.运维规模及种类 我相信,这也是 ...

  3. 原生js封装轮播图

    个人实际开发中用到的效果问题总结出来便于自己以后开发查看调用,如果也适用其他人请随意拿走勿喷就行! 原生js对于思路要求比较高,在js代码我都写有备注,足够理解并使用,即使是小白或者刚入行的程序员也比 ...

  4. Hexo+NexT(零):最全Hexo+Next搭建博客教程

    快速.简洁且高效的博客框架 有位大神说,喜欢写博客的人的人,折腾博客会经历三个阶段.找到一个免费空间,搭建一个博客,很欣喜,很有成就感,此为一阶段:受限免费空间各种限制,自己买空间和域名,实现对博客的 ...

  5. Hadoop 学习之路(七)—— HDFS Java API

    一. 简介 想要使用HDFS API,需要导入依赖hadoop-client.如果是CDH版本的Hadoop,还需要额外指明其仓库地址: <?xml version="1.0" ...

  6. Salesforce LWC学习(二) helloWorld程序在VSCode中的实现

    上一篇我们简单的描述了一下Salesforce DX的配置以及CLI的简单功能使用,此篇主要简单描述一下LWC如何实现helloWorld以及LWC开发时应该注意的一些规范. 做国内项目的同学直观的感 ...

  7. Java学习笔记——设计模式之十.观察者模式

     观察者模式(Observer),定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己. Subject类: ...

  8. PATA 1009. Product of Polynomials (25)

    1009. Product of Polynomials (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yu ...

  9. IIS下网站对options请求直接返回404

    什么是options请求 options请求为发送非简单跨域请求前的预检请求,若该请求未正常返回,浏览器会阻止后续的请求发送. 一般情况下,有三种方式会导致浏览器发起预检请求 1.请求的方法不是GET ...

  10. mail.inc实现周密的留言发邮箱

    我网站上很多地方都有给我留言的链接,这些链接指向一个地方 http://www.dushangself.site/emlog/?post=8 (源码使用方式:一共四个源代码,第一个和第二个写在一起,, ...