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