大话设计模式--DI(依赖注入)
1.背景
想象一个场景:有个功能通过某个参数决定了路由到不同的方法上或者几个方法模块可以自由搭配,咋办?一般人会对每个方法写一个helper(比如SendMessageForEmail、SendMessageForSMS).
2.分析
这样的方法可以吗?当然可以实现,而且跑起来压根没问题,如果你想让自己代码更好一点,更有结构更容易维护,你需要做一些事,用到DI依赖注入模式
3.代码
一般方法:
1 private bool callSendNote(int tenant_id, string app_id, string user_Id, string domamin,int sendNoteType,string email,string mobile) 2 { 3 var flagForEamil = true; 4 var flagForMobile = true; 5 //生成Url 6 var emailUrl = AuthorityHelper.GetUrl(tenant_id, app_id, user_Id, "2", domamin); 7 var messageUrl = AuthorityHelper.GetUrl(tenant_id, app_id, user_Id, "3", domamin); 8 var emailContent = BeisenNPSConfig.EmailContent; 9 var emailSubject = BeisenNPSConfig.EmailSubject; 10 var messageContent = BeisenNPSConfig.MessageContent; 11 12 switch (sendNoteType) { 13 case 1: 14 if (!string.IsNullOrEmpty(email)) 15 { 16 flagForEamil = MailSendHelper.SendMail("ue@beisen.com", "北森", new string[] { email }, string.Format(emailContent, domamin, emailUrl, emailUrl, emailUrl, domamin), emailSubject); 17 } 18 break; 19 case 2: 20 if (!string.IsNullOrEmpty(mobile)) 21 { 22 var smsMessage = new List<SMSMessage>() { new SMSMessage() { Phone = mobile, Message = string.Format(messageContent, messageUrl) } }; 23 flagForMobile = SMSSendHelper.SendSms(smsMessage); 24 } 25 break; 26 case 3: 27 if (!string.IsNullOrEmpty(email)) 28 { 29 flagForEamil = MailSendHelper.SendMail("ue@beisen.com", "北森", new string[] { email }, string.Format(emailContent, domamin, emailUrl, emailUrl, emailUrl, domamin), emailSubject); 30 } 31 if (!string.IsNullOrEmpty(mobile)) 32 { 33 var smsMessage = new List<SMSMessage>() { new SMSMessage() { Phone = mobile, Message = string.Format(messageContent, messageUrl) } }; 34 flagForMobile = SMSSendHelper.SendSms(smsMessage); 35 } 36 break; 37 default:break; 38 } 39 return (flagForEamil && flagForMobile); 40 }
两个helper:
1 public class MailSendHelper 2 { 3 #region Fields 4 static readonly ILog Logger = Logging.LogWrapper.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.FullName); 5 #endregion 6 public static bool SendMail(string from, string displayName, string[] to, string body, string subject, int TenantId = 2, string TenantName = "北森", string SystemId = "PlatformSHMail") 7 { 8 try 9 { 10 Logger.ErrorFormat("开始发送邮件! count:{0}=====>detail:{1}", to.Count(), string.Join(",", to)); 11 12 if (string.IsNullOrEmpty(from)) from = "italent@italent.cn"; 13 MailBatch batch = new MailBatch(); 14 batch.SystemId = SystemId; 15 batch.TenantId = TenantId; 16 batch.TenantName = TenantName; 17 batch.Title = subject; 18 batch.MailMessages = new MailMessageCollection(); 19 batch.CalendarType = CalendarMail.Normal; 20 batch.EMailType = EmailType.Normal; 21 batch.Cancel = false; 22 foreach (var item in to) 23 { 24 if (!string.IsNullOrEmpty(item)) 25 batch.MailMessages.Add(new MailMessage() 26 { 27 Body = body, 28 Subject = subject, 29 Priority = MailPriority.Normal, 30 IsUseTemplate = false, 31 IsBodyHtml = true, 32 33 From = new MailAddress() 34 { 35 Address = from, 36 DisplayName = displayName 37 }, 38 To = new MailAddressCollection() 39 { 40 new MailAddress() 41 { 42 Address = item, 43 DisplayName = item 44 } 45 } 46 }); 47 } 48 batch.Update = false; 49 var batch_id = SMSMailProvider.Mail_SendMailByBatch(batch); 50 if (!string.IsNullOrEmpty(batch_id)) 51 { 52 Logger.Debug("邮件发送成功!batch_id:" + batch_id); 53 return true; 54 } 55 else 56 return false; 57 } 58 catch (Exception ex) 59 { 60 Logger.Error(string.Format("邮件发送失败! tenantId:{0}=====>to:{1}", TenantId, string.Join(",", to)), ex); 61 return false; 62 } 63 } 64 #region Properties 65 public static ISMSMailProvider SMSMailProvider 66 { 67 get 68 { 69 return ESBDynamicProxy.GetInstance<ISMSMailProvider>(); 70 } 71 } 72 #endregion 73 }
1 public class SMSSendHelper 2 { 3 #region Fields 4 static readonly ILog Logger = Logging.LogWrapper.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.FullName); 5 #endregion 6 public static bool SendSms(IEnumerable<SMSMessage> smsMessageList, int TenantId = 2, string TenantName = "北森", string SystemId = "CommonPIN", string SolutionName = "UPaas") 7 { 8 //Todo:批量一次只能发一万条 9 try 10 { 11 Logger.Error(string.Format("开始发送短信! count:{0}=====>detail:{1}", smsMessageList.Count(),Newtonsoft.Json.JsonConvert.SerializeObject(smsMessageList))); 12 13 SMSBatch batch = new SMSBatch(); 14 batch.ShortMessages = new MessageCollection { }; 15 foreach (var smsMessage in smsMessageList) 16 { 17 if (string.IsNullOrEmpty(smsMessage.Phone)) { continue; } 18 //判断短信内容是否为黑词 19 string black = ""; 20 bool isExist = ArgumentHelper.CheckBlackWord(smsMessage.Message, out black); 21 if (isExist == true) 22 { 23 string[] blacks = black.Split(','); 24 foreach (var blackWord in blacks) 25 { 26 smsMessage.Message = smsMessage.Message.Replace(blackWord, ""); 27 } 28 } 29 if (smsMessage.Message.Length >= 500) 30 { 31 smsMessage.Message = smsMessage.Message.Substring(0, 430) + "......"; 32 } 33 var msg = new ShortMessage 34 { 35 MessageText = smsMessage.Message, 36 PhoneNumber = smsMessage.Phone 37 }; 38 batch.ShortMessages.Add(msg); 39 } 40 41 batch.SystemId = SystemId; 42 batch.TenantId = TenantId; 43 batch.TenantName = TenantName; 44 batch.SolutionName = SolutionName; 45 ArgumentHelper.IsValid(batch, true); 46 string batchId = SMSMailProvider.SMS_SendSMSAnyTime(batch); 47 48 if (string.IsNullOrEmpty(batchId)) 49 { 50 return false; 51 } 52 else 53 { 54 return true; 55 } 56 } 57 catch (Exception ex) 58 { 59 Logger.Error(string.Format("短信发送失败! tenantId:{0}=====>detail:{1}", TenantId, Newtonsoft.Json.JsonConvert.SerializeObject(smsMessageList)), ex); 60 } 61 62 return true; 63 } 64 65 #region Properties 66 public static ISMSMailProvider SMSMailProvider 67 { 68 get 69 { 70 return ESBDynamicProxy.GetInstance<ISMSMailProvider>(); 71 } 72 } 73 #endregion 74 }
如果使用依赖注入的话
则是:
首先创建个接口,就是两个模块的抽象,ISendNoteService
public interface ISendNoteService { void SendMesssage(BaseAgrs agrs); } public class BaseAgrs { public int tenant_id { get; set; } public string app_id { get; set; } public string user_Id { get; set; } public string domamin { get; set; } public int sendNoteType { get; set; } public string email { get; set; } public string mobile { get; set; } public string TenantId { get; set; } public string TenantName { get; set; } public string SystemId { get; set; } }
两个模块服务类都有
ISendNoteService这个接口构造函数注入
如下:
SendEmailService类:
public class SendEmailService { private ISendNoteService _iSendNoteService; public SendEmailService(ISendNoteService _sendNoteService) { _iSendNoteService = _sendNoteService; } public void SendMessage(EmailAgrs agrs) { _iSendNoteService.SendMesssage(agrs); } } public class EmailAgrs:BaseAgrs { public string from { get; set; } public string displayName { get; set; } public string[] to { get; set; } public string body { get; set; } public string subject { get; set; } }
SendSMService类:
public class SendSMService { private ISendNoteService _iSendNoteService; public SendSMService(ISendNoteService _sendNoteService) { _iSendNoteService = _sendNoteService; } public void SendMessage(MobileAgrs agrs) { _iSendNoteService.SendMesssage(agrs); } } public class MobileAgrs : BaseAgrs { public IEnumerable<SMSMessage> smsMessageList { get; set; } }
在调用的过程中,构造好不同的model后,直接再provider调用不同的service即可