feat(domain): add value objects for email domain
- MessageId: Unique message identifier with SHA256 hash
Uses same algorithm as legacy system for duplicate detection compatibility
Hash format: SHA256({originalMessageId}|{sender}|{date}|{subject})
- EmailAddress: Email address validation and parsing with name support
Value objects ensure immutability and value-based equality.
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using DigitalData.EmailProfiler.Domain.Common;
|
||||
using DigitalData.EmailProfiler.Domain.Exceptions;
|
||||
|
||||
namespace DigitalData.EmailProfiler.Domain.ValueObjects;
|
||||
|
||||
/// <summary>
|
||||
/// Value object representing an email address with validation
|
||||
/// </summary>
|
||||
public class EmailAddress : ValueObject
|
||||
{
|
||||
public string Value { get; private set; }
|
||||
public string Domain { get; private set; }
|
||||
public string LocalPart { get; private set; }
|
||||
|
||||
private EmailAddress(string value)
|
||||
{
|
||||
Value = value;
|
||||
var parts = value.Split('@');
|
||||
LocalPart = parts[0];
|
||||
Domain = parts[1];
|
||||
}
|
||||
|
||||
public static EmailAddress Create(string email)
|
||||
{
|
||||
if (!IsValid(email))
|
||||
throw new DomainException($"Invalid email address: {email}");
|
||||
|
||||
return new EmailAddress(email.ToLowerInvariant());
|
||||
}
|
||||
|
||||
private static bool IsValid(string email)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(email) &&
|
||||
email.Contains('@') &&
|
||||
new EmailAddressAttribute().IsValid(email);
|
||||
}
|
||||
|
||||
protected override IEnumerable<object> GetEqualityComponents()
|
||||
{
|
||||
yield return Value;
|
||||
}
|
||||
|
||||
public override string ToString() => Value;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using DigitalData.EmailProfiler.Domain.Common;
|
||||
|
||||
namespace DigitalData.EmailProfiler.Domain.ValueObjects;
|
||||
|
||||
/// <summary>
|
||||
/// Value object representing a unique message identifier with hash generation
|
||||
/// Uses the same algorithm as legacy system for compatibility
|
||||
/// </summary>
|
||||
public class MessageId : ValueObject
|
||||
{
|
||||
public string Value { get; private set; }
|
||||
public string Hash { get; private set; }
|
||||
|
||||
private MessageId(string value)
|
||||
{
|
||||
Value = value;
|
||||
Hash = GenerateHash(value);
|
||||
}
|
||||
|
||||
public static MessageId Create(string originalMessageId, string sender, DateTime date, string subject)
|
||||
{
|
||||
var combined = $"{originalMessageId}|{sender}|{date:yyyyMMddHHmmss}|{subject}";
|
||||
return new MessageId(combined);
|
||||
}
|
||||
|
||||
private static string GenerateHash(string input)
|
||||
{
|
||||
// Same algorithm as legacy: SHA256 hash
|
||||
using var sha256 = SHA256.Create();
|
||||
var bytes = Encoding.UTF8.GetBytes(input);
|
||||
var hash = sha256.ComputeHash(bytes);
|
||||
return Convert.ToBase64String(hash);
|
||||
}
|
||||
|
||||
protected override IEnumerable<object> GetEqualityComponents()
|
||||
{
|
||||
yield return Value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user