Skip to content

Instantly share code, notes, and snippets.

@spewu
Last active February 15, 2024 16:31
Show Gist options
  • Save spewu/5933739 to your computer and use it in GitHub Desktop.
Save spewu/5933739 to your computer and use it in GitHub Desktop.
Better enums in C# for DDD ... based on Jimmy Bogards Enumeration class
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
[Serializable]
[DebuggerDisplay("{DisplayName} - {Value}")]
public abstract class Enumeration<TEnumeration, TValue> : IComparable<TEnumeration>, IEquatable<TEnumeration>
where TEnumeration : Enumeration<TEnumeration, TValue>
where TValue : IComparable
{
private static readonly TEnumeration[] Enumerations = GetEnumerations();
private readonly string displayName;
private readonly TValue value;
protected Enumeration(TValue value, string displayName)
{
this.value = value;
this.displayName = displayName;
}
public TValue Value
{
get { return value; }
}
public string DisplayName
{
get { return displayName; }
}
public static TEnumeration[] GetAll()
{
return Enumerations;
}
public static TEnumeration FromValue(TValue value)
{
return Parse(value, "value", item => item.Value.Equals(value));
}
public static TEnumeration Parse(string displayName)
{
return Parse(displayName, "display name", item => item.DisplayName == displayName);
}
public static bool TryParse(TValue value, out TEnumeration result)
{
return TryParse(x => x.Value.Equals(value), out result);
}
public static bool TryParse(string displayName, out TEnumeration result)
{
return TryParse(x => x.DisplayName == displayName, out result);
}
public int CompareTo(TEnumeration other)
{
return Value.CompareTo(other.Value);
}
public override sealed string ToString()
{
return DisplayName;
}
public override bool Equals(object obj)
{
return Equals(obj as TEnumeration);
}
public bool Equals(TEnumeration other)
{
return other != null && Value.Equals(other.Value);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
private static bool TryParse(Func<TEnumeration, bool> predicate, out TEnumeration result)
{
result = GetAll().FirstOrDefault(predicate);
return result != null;
}
private static TEnumeration[] GetEnumerations()
{
var enumerationType = typeof(TEnumeration);
return enumerationType
.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)
.Where(info => enumerationType.IsAssignableFrom(info.FieldType))
.Select(info => info.GetValue(null))
.Cast<TEnumeration>()
.ToArray();
}
private static TEnumeration Parse(object value, string description, Func<TEnumeration, bool> predicate)
{
TEnumeration result;
if (!TryParse(predicate, out result))
{
var message = string.Format("'{0}' is not a valid {1} in {2}", value, description, typeof(TEnumeration));
throw new ArgumentException(message, "value");
}
return result;
}
}
public abstract class EmailType : Enumeration<EmailType, int>
{
public static readonly EmailType AnythingElse = new AnythingElseType();
public static readonly EmailType SpecialEmail = new SpecialEmailType();
protected EmailType(int value, string displayName) : base(value, displayName)
{
}
protected static string SendGridSmtp
{
get { return "smtp.sendgrid.net"; }
}
protected static int SendGridPort
{
get { return 587; }
}
public abstract SmtpSettings GetSmtpSettings();
private class AnythingElseType : EmailType
{
public AnythingElseType() : base(0, "AnythingElse")
{
}
public override SmtpSettings GetSmtpSettings()
{
return new SmtpSettings
{
Port = SendGridPort,
Server = SendGridSmtp,
UseSsl = true,
Username = "some@user.com",
Password = "somePassword"
};
}
}
private class SpecialEmailType : EmailType
{
public SpecialEmailType() : base(1, "SpecialEmail")
{
}
public override SmtpSettings GetSmtpSettings()
{
return new SmtpSettings
{
Port = SendGridPort,
Server = SendGridSmtp,
UseSsl = true,
Username = "another@user.com",
Password = "anotherPassword"
};
}
}
}
public void Main()
{
var emailType = EmailType.SpecialEmail;
var mailMessage = new MailMessage("from@user.com", "to@user.com", "Test", "This is a test email");
SendMail(emailType, mailMessage);
}
public void SendMail(EmailType emailType, MailMessage mailMessage)
{
using(var smtpClient = emailType.GetSmtpSettings().CreateSmtpClient())
{
smtpClient.Send(mailMessage);
}
}
using System.Net;
using System.Net.Mail;
public class SmtpSettings
{
public string Server { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public bool UseSsl { get; set; }
public int Port { get; set; }
public SmtpClient CreateSmtpClient()
{
return new SmtpClient(Server, Port)
{
Credentials = new NetworkCredential(Username, Password),
EnableSsl = UseSsl,
DeliveryMethod = SmtpDeliveryMethod.Network,
};
}
}
@OctavioLuiz
Copy link

well played!

@spk33
Copy link

spk33 commented Aug 3, 2021

Cool Idea Thanks for this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment