diff --git a/src/SampleProject.Application/Customers/DomainServices/CustomerEmailChecker.cs b/src/SampleProject.Application/Customers/DomainServices/CustomerEmailChecker.cs new file mode 100644 index 0000000..800c791 --- /dev/null +++ b/src/SampleProject.Application/Customers/DomainServices/CustomerEmailChecker.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Net.Mail; +using System.Text; +using SampleProject.Domain.Customers; + +namespace SampleProject.Application.Customers.DomainServices +{ + class CustomerEmailChecker : ICustomerEmailChecker + { + private readonly string _customerEmail; + + public CustomerEmailChecker(string customerEmail) + { + _customerEmail = customerEmail; + } + + public bool IsValid(string customerEmail) + { + try + { + var emailAddress = new MailAddress(customerEmail); + } + catch + { + return false; + } + + return true; + } + } +} diff --git a/src/SampleProject.Application/Customers/RegisterCustomer/RegisterCustomerCommandHandler.cs b/src/SampleProject.Application/Customers/RegisterCustomer/RegisterCustomerCommandHandler.cs index 4dee03c..2bdf419 100644 --- a/src/SampleProject.Application/Customers/RegisterCustomer/RegisterCustomerCommandHandler.cs +++ b/src/SampleProject.Application/Customers/RegisterCustomer/RegisterCustomerCommandHandler.cs @@ -13,20 +13,29 @@ public class RegisterCustomerCommandHandler : ICommandHandler Handle(RegisterCustomerCommand request, CancellationToken cancellationToken) { - var customer = Customer.CreateRegistered(request.Email, request.Name, this._customerUniquenessChecker); + var customer = Customer.CreateRegistered(request.Email, request.Name, this._customerUniquenessChecker, this._customerEmailChecker); + + if (customer == null) + { + // What is the best way to return error to user? + return new CustomerDto(); + } await this._customerRepository.AddAsync(customer); diff --git a/src/SampleProject.Domain/Customers/Customer.cs b/src/SampleProject.Domain/Customers/Customer.cs index 14bbe6e..1dfd82a 100644 --- a/src/SampleProject.Domain/Customers/Customer.cs +++ b/src/SampleProject.Domain/Customers/Customer.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Linq.Expressions; +using System.Net.Mail; using SampleProject.Domain.Customers.Orders; using SampleProject.Domain.Customers.Orders.Events; using SampleProject.Domain.Customers.Rules; @@ -30,9 +33,9 @@ private Customer() private Customer(string email, string name) { this.Id = new CustomerId(Guid.NewGuid()); - _email = email; - _name = name; - _welcomeEmailWasSent = false; + SetCustomerEmail(email); + SetCustomerName(name); + SetWelcomeEmailSentStatus(false); _orders = new List(); this.AddDomainEvent(new CustomerRegisteredEvent(this.Id)); @@ -41,10 +44,32 @@ private Customer(string email, string name) public static Customer CreateRegistered( string email, string name, - ICustomerUniquenessChecker customerUniquenessChecker) + ICustomerUniquenessChecker customerUniquenessChecker, + ICustomerEmailChecker customerEmailChecker = null) { - CheckRule(new CustomerEmailMustBeUniqueRule(customerUniquenessChecker, email)); - + try + { + if (customerEmailChecker != null) + { + CheckRule(new CustomerEmailValidRule(customerEmailChecker, email)); + } + } + catch (BusinessRuleValidationException ex) + { + return null; + } + + try + { + + CheckRule(new CustomerEmailMustBeUniqueRule(customerUniquenessChecker, email)); + } + + catch(BusinessRuleValidationException ex) + { + //FIXME: Maybe throw duplicate email exception? Or log the error? + return null; + } return new Customer(email, name); } @@ -91,7 +116,22 @@ public void RemoveOrder(OrderId orderId) public void MarkAsWelcomedByEmail() { - this._welcomeEmailWasSent = true; + SetWelcomeEmailSentStatus(true); + } + + private void SetCustomerEmail(string email) + { + _email = email; + } + + private void SetCustomerName(string name) + { + _name = name; + } + + private void SetWelcomeEmailSentStatus(bool wasSent) + { + _welcomeEmailWasSent = wasSent; } } } \ No newline at end of file diff --git a/src/SampleProject.Domain/Customers/ICustomerEmailChecker.cs b/src/SampleProject.Domain/Customers/ICustomerEmailChecker.cs new file mode 100644 index 0000000..7e5d833 --- /dev/null +++ b/src/SampleProject.Domain/Customers/ICustomerEmailChecker.cs @@ -0,0 +1,7 @@ +namespace SampleProject.Domain.Customers +{ + public interface ICustomerEmailChecker + { + bool IsValid(string customerEmail); + } +} \ No newline at end of file diff --git a/src/SampleProject.Domain/Customers/Rules/CustomerEmailValidRule.cs b/src/SampleProject.Domain/Customers/Rules/CustomerEmailValidRule.cs new file mode 100644 index 0000000..e226a5b --- /dev/null +++ b/src/SampleProject.Domain/Customers/Rules/CustomerEmailValidRule.cs @@ -0,0 +1,27 @@ +using SampleProject.Domain.SeedWork; + +namespace SampleProject.Domain.Customers.Rules +{ + internal class CustomerEmailValidRule : IBusinessRule + { + private readonly ICustomerEmailChecker _customerEmailChecker; + + private readonly string _email; + + public CustomerEmailValidRule( + ICustomerEmailChecker customerEmailChecker, + string email) + { + _customerEmailChecker = customerEmailChecker; + _email = email; + } + + public bool IsBroken() + { + return !_customerEmailChecker.IsValid(_email); + } + + + public string Message => "Customer with this email already exists."; + } +} \ No newline at end of file diff --git a/src/SampleProject.Infrastructure/Domain/DomainModule.cs b/src/SampleProject.Infrastructure/Domain/DomainModule.cs index 892eb4e..4b09c4f 100644 --- a/src/SampleProject.Infrastructure/Domain/DomainModule.cs +++ b/src/SampleProject.Infrastructure/Domain/DomainModule.cs @@ -14,6 +14,10 @@ protected override void Load(ContainerBuilder builder) .As() .InstancePerLifetimeScope(); + builder.RegisterType() + .As() + .InstancePerLifetimeScope(); + builder.RegisterType() .As() .InstancePerLifetimeScope();