动态加载方法(定时任务)
背景: 向用户推送使用即将过期优惠券的消息,做成通用发送功能,方便将来对推送消息的扩展
思路: 实现类实现DynamicMethod接口中通用Execute方法以实现不同的推送,再在通用发送实例使用反射动态加载。
代码:
1。先定义接口
1 public interface IDynamicBackgroundJobs 2 { 3 void Execute(string dynamicMsg); 4 }
2。Model
1. BaseBackgroundJobs(基类:只存在这个任务中总是会用到的手机号)
/// <summary> /// 用户手机号 /// </summary> public string MobilePhoneNo { get; set; }
2. PromotionInfo(优惠信息模板,继承基类)
public partial class PromotionInfo: BaseBackgroundJobs { /// <summary> /// 用户编号 /// </summary> public int UserId { get; set; } /// <summary> /// 优惠券名称 /// </summary> //public string Explain { get; set; } /// <summary> /// 优惠券执行时间 /// </summary> public DateTime RunTime { get; set; } }
3. BackgroundJobsModel(通用消息存储模板)
public class BackgroundJobsModel { /// <summary> /// 消息编号 /// </summary> public int MessageId { get; set; } /// <summary> /// 执行时间 /// </summary> public DateTime RunTime { get; set; } /// <summary> /// 消息数据 /// </summary> public string MessageData { get; set; } /// <summary> /// 消息类型(命名空间) /// </summary> public string MessageType { get; set; } }
3。实现类(Execute方法需要通用发送类提供手机号)
public class PromotionCodeService : HandleBackgroundJobsService<PromotionInfo, RestfulModel>, IDynamicBackgroundJobs { //ApiUser接口数据模型 ApiUser _userApi; List<ApiUser> _userApiList; OutputDto<ApiUser> _userApiDto; PromotionCodeDAL _promotionCodeDAL; PromotionInfo _promotionInfo; RestfulModel _restfulModel; SendBackgroundJobsService<PromotionInfo> _sendBackgroundJobsService; public PromotionCodeService() { _userApi = new ApiUser(); _userApiDto = new OutputDto<ApiUser>(); _userApiList = new List<ApiUser>(); _promotionCodeDAL = new PromotionCodeDAL(); _promotionInfo = new PromotionInfo(); _sendBackgroundJobsService = new SendBackgroundJobsService<PromotionInfo>(); } /// <summary> /// 控制器调用的存储数据方法 /// <para> runTime.任务执行时间</para> /// </summary> /// <param name="runTime"></param> public void StoreDataTest(DateTime runTime) { //获取优惠数据集合 var promotionInfoList = _promotionCodeDAL.GetPromotionInfo(); //获取命名空间 string backgroundJobsModelMessageType = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName; //插入数据库 InsertBackgroundJobsModel(runTime, promotionInfoList, backgroundJobsModelMessageType); } /// <summary> /// 控制器调用的发送方法 /// </summary> /// <param name="planTime"></param> public void SendData(DateTime planTime) { _sendBackgroundJobsService.SendBackgroundJobsModelList(planTime); } /// <summary> /// 通用执行方法 /// </summary> /// <param name="phone"></param> public void Execute(string phone) { _restfulModel = new RestfulModel(); _restfulModel.ETyp1 = "1"; _restfulModel.SkipType = "4"; _restfulModel.Msg = "您的优惠券即将到期,快来使用吧!"; MessageService.SendJpush(new Common.Service.Dto.JPushDto { KeyValues = new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>("EType", _restfulModel.ETyp1), new KeyValuePair<string, string>("SkipType",_restfulModel.SkipType) }, Phone = _restfulModel.MobilePhoneNo, Msg = _restfulModel.Msg }); } }
4。通用处理类(实现类的父类,处理数据,并存入数据库)
/// <summary> /// 通用消息处理 /// </summary> /// <typeparam name="TJob"></typeparam> /// <typeparam name="Targs"></typeparam> public partial class HandleBackgroundJobsService<TJob,Targs> where TJob:BaseBackgroundJobs where Targs : BaseBackgroundJobs { BackgroundJobsDAL _backgroundJobsDAL; BackgroundJobsModel _backgroundJobsModel; List<BackgroundJobsModel> _backgroundJobsModelList; public HandleBackgroundJobsService() { _backgroundJobsDAL = new BackgroundJobsDAL(); _backgroundJobsModel = new BackgroundJobsModel(); _backgroundJobsModelList = new List<BackgroundJobsModel>(); } /// <summary> /// 数据类型转化为后台数据对象 /// <para>jobs 集合类型</para> /// </summary> /// <param name="jobs"></param> /// <param name="backgroundJobsModelMessageType"></param> List<BackgroundJobsModel> public List<BackgroundJobsModel> GetBackgroundJobsModel(DateTime runTime, List<TJob> jobs, string backgroundJobsModelMessageType) { foreach (var promotionInfo in jobs) { _backgroundJobsModelList = jobs.Select(p => new BackgroundJobsModel() { RunTime = runTime, MessageData = JsonConvert.SerializeObject(promotionInfo), MessageType = backgroundJobsModelMessageType }).ToList(); } return _backgroundJobsModelList; } /// <summary> /// 插入后台模板数据至数据库 /// <para>(PromotionInfo)List promotionInfoList</para> /// <para>string backgroundJobsModelMessageType</para> /// </summary> /// <param name="promotionInfoList"></param> /// <param name="backgroundJobsModelMessageType"></param> public void InsertBackgroundJobsModel(DateTime runTime, List<TJob> jobs, string backgroundJobsModelMessageType) { _backgroundJobsModelList = GetBackgroundJobsModel(runTime, jobs, backgroundJobsModelMessageType); _backgroundJobsDAL.InsertBackgroundJobsModelListDal(_backgroundJobsModelList); } }
5。通用发送类(通过反射动态加载实现类中的Execute方法)
public partial class SendBackgroundJobsService<TJob>where TJob:BaseBackgroundJobs { BackgroundJobsDAL _backgroundJobsDAL; BackgroundJobsModel _backgroundJobsModel; List<BackgroundJobsModel> _backgroundJobsModelList; public SendBackgroundJobsService() { _backgroundJobsDAL = new BackgroundJobsDAL(); _backgroundJobsModel = new BackgroundJobsModel(); _backgroundJobsModelList = new List<BackgroundJobsModel>(); } /// <summary> /// 扫描后台数据 /// </summary> /// <returns></returns> public List<BackgroundJobsModel> ScanBackgroundJobsModelList() { var backgroundJobsModelList = _backgroundJobsDAL.ScanBackgroundJobsModelList(); return backgroundJobsModelList; } /// <summary> /// 发送数据,数据会自动删除 /// </summary> public void SendBackgroundJobsModelList(DateTime planTime) { //传入手机号 var phone = string.Empty; var backgroundJobsModelList = ScanBackgroundJobsModelList(); foreach (var backgroundJobsModel in backgroundJobsModelList) { if (backgroundJobsModel.RunTime >planTime)//调试使用> { //命名空间 var jobType = Type.GetType(backgroundJobsModel.MessageType); ////动态创建消息扫描类的实例 //var SendDataService = (HandleBackgroundJobsService<TJob,Targs>)Activator.CreateInstance(jobType); //动态调用扫描数据库方法 //动态创建实例 var obj = Activator.CreateInstance(jobType); var dynamicMethod = jobType.GetMethod("Execute"); var primaryData = JsonConvert.DeserializeObject<TJob>(backgroundJobsModel.MessageData); phone = primaryData.MobilePhoneNo; //调用函数执行任务 dynamicMethod.Invoke(obj, new object[] { phone }); //删除数据 _backgroundJobsDAL.DeleteSentData(backgroundJobsModel.MessageId); } }
本文重点是 4,5两个步骤。代码都是在业务类和模板类中代码,主要提供思路和逻辑,具体使用什么Execute、什么数据库和获取数据方式由阅读者自行补充。
ps。有什么意见和建议请提出,博主尽量解决。