To avoid switch
statements at multiple places, I wrote the following code. This was based on articles found in the Google search. The object names are not real in the sample below. So please ignore that.
//somewhere in the code
foreach (IEmailAlertDt alert in EmailAlertFactory.GetEmailAlertDtType(allowedEmails))
{
if (alert.CheckEmailAlertDt(currReason))
{
SendEmail(alert.EmailSubject(patRegister.Pat.Id.ToString()), alert.EmailBody(patRegister.Pat.Id.ToString(), patRegister.Organ.Descrip));
alert.UpdateEmailAlertDt(currReason);
}
}
[Flags]
enum EmailAlertType
{
NoAlert=0,
FirstAlert=1,
SecondAlert=2,
ThirdAlert=4
};
static class EmailAlertFactory
{
private static Dictionary<EmailAlertType, Func<IList<IEmailAlertDt>>> EmailAlertMap = new Dictionary<EmailAlertType, Func<IList<IEmailAlertDt>>>
{
{EmailAlertType.FirstAlert,()=> new List<IEmailAlertDt>() {new FisrtEmailAlertDt() } },
{EmailAlertType.FirstAlert | EmailAlertType.SecondAlert ,()=> new List<IEmailAlertDt>() {new FisrtEmailAlertDt(), new SecondEmailAlertDt() } },
{EmailAlertType.FirstAlert | EmailAlertType.SecondAlert | EmailAlertType.ThirdAlert,()=> new List<IEmailAlertDt>() {new FisrtEmailAlertDt(), new SecondEmailAlertDt(), new ThirdEmailAlertDt() } }
};
public static IList<IEmailAlertDt> GetEmailAlertDtType(EmailAlertType alertType)
{
return EmailAlertMap[alertType]();
}
}
interface IEmailAlertDt
{
bool CheckEmailAlertDt(PatWaitListStatReason reason);
void UpdateEmailAlertDt(PatWaitListStatReason reason);
string EmailBody(string patID, string Organ);
string EmailSubject(string patID);
}
class FisrtEmailAlertDt : IEmailAlertDt
{
public bool CheckEmailAlertDt(PatWaitListStatReason reason)
{
if (reason.EmailAlertFirstDate == null)
return true;
else
return false;
}
public void UpdateEmailAlertDt(PatWaitListStatReason reason)
{
if (reason.EmailAlertFirstDate == null)
reason.EmailAlertFirstDate = DateTime.Today;
}
public string EmailBody(string patID, string Organ)
{
return String.Format(PatOnHoldSuspension.emailBody, PatOnHoldSuspension.FIRST_ALERT_DAYS, patID, Organ);
}
public string EmailSubject(string patID)
{
return String.Format(PatOnHoldSuspension.emailSubject, PatOnHoldSuspension.FIRST_ALERT_DAYS,patID);
}
}
class SecondEmailAlertDt : IEmailAlertDt
{
public bool CheckEmailAlertDt(PatWaitListStatReason reason)
{
if (reason.EmailAlertSecondDate == null)
return true;
else
return false;
}
public void UpdateEmailAlertDt(PatWaitListStatReason reason)
{
if (reason.EmailAlertSecondDate == null)
reason.EmailAlertSecondDate = DateTime.Today;
}
public string EmailBody(string patID, string Organ)
{
return String.Format(PatOnHoldSuspension.emailBody, PatOnHoldSuspension.SECOND_ALERT_DAYS, patID, Organ);
}
public string EmailSubject(string patID)
{
return String.Format(PatOnHoldSuspension.emailSubject, PatOnHoldSuspension.SECOND_ALERT_DAYS, patID);
}
}
class ThirdEmailAlertDt : IEmailAlertDt
{
public bool CheckEmailAlertDt(PatWaitListStatReason reason)
{
if (reason.EmailAlertThirdDate == null)
return true;
else
return false;
}
public void UpdateEmailAlertDt(PatWaitListStatReason reason)
{
if (reason.EmailAlertThirdDate == null)
reason.EmailAlertThirdDate = DateTime.Today;
}
public string EmailBody(string patID, string Organ)
{
return String.Format(PatOnHoldSuspension.emailBody120, PatOnHoldSuspension.THIRD_ALERT_DAYS, patID, Organ);
}
public string EmailSubject(string patID)
{
return String.Format(PatOnHoldSuspension.emailSubject120, patID);
}
}
The things that bother me is that there are different small methods like CheckEmailAlertDt
, with minor difference. In the first date1
is used and in seconds one date2
is used. Is there any way I can further optimise/streamline this code?
switch
? \$\endgroup\$classDt
orderclass1
. :-) \$\endgroup\$switch
and with our constantly changing requirement it is easy to make mistakes. As I mentioned, in the question, you can ignore names for this question. In the actual App, there are better names used \$\endgroup\$