public void RecommendAFriend(int referrerId, NewAccount friendsAccountDetails) { Validate(friendsAccountDetails); using (var transaction = new System.Transactions.TransactionScope()) { try { var referrer = customerDirectory.Find(referrerId); var friend = customerDirectory.Add(friendsAccountDetails); referAFriendPolicy.Apply(referrer, friend); transaction.Complete(); var msg = new CustomerRegisteredViaReferralPolicy { ReferrerId = referrerId, FriendId = friend.Id }; bus.Publish(msg); } catch (ReferralRejectedDueToLongTermOutstandingBalance) { var msg = new ReferralSignupRejected { ReferrerId = referrerId, FriendEmail = friendsAccountDetails.Email, Reason = "Referrer has long term outstanding balance" }; bus.Publish(msg); } } }
public void RecommendAFriend(int referrerId, NewAccount friend) { // validation, open transaction etc var command = new RecommendAFriend { ReferrerId = referrerId, Friend = friend }; Task.Factory.StartNew(() => policy.Apply(command)); // close transaction - success and failure handled in handlers }
private void Validate(NewAccount account) { // ... }
// technical validation carried out at the application level private void Validate(NewAccount account) { if (!account.Email.Contains("@")) throw new ValidationFailure("Not a valid email address"); if (account.Email.Length >= 50) throw new ValidationFailure("Email address must be less than 50 characters"); if (account.Nickname.Length >= 25) throw new ValidationFailure("Nickname must be less than 25 characters"); if (String.IsNullOrWhiteSpace(account.Email)) throw new ValidationFailure("You must supply an email"); if (String.IsNullOrWhiteSpace(account.Nickname)) throw new ValidationFailure("You must supply a Nickname"); }
public void RecommendAFriend(int referrerId, NewAccount friendsAccountDetails) { Validate(friendsAccountDetails); // most technologies have similar transaction APIs using (var transaction = new System.Transactions.TransactionScope()) { try { // customerDirectory is a domain repository var referrer = customerDirectory.Find(referrerId); var friend = customerDirectory.Add(friendsAccountDetails); // referAFriend policy is a domain policy referAFriendPolicy.Apply(referrer, friend); transaction.Complete(); // log here to keep to avoid cluttering domain logger.Debug("Successful friend recommendation"); StatsdClient.Metrics.Counter("friendReferrals"); } catch (ReferralRejectedDueToLongTermOutstandingBalance ex) { logger.Error(ex); StatsdClient.Metrics.Counter("ReferralRejected"); throw new ApplicationError( "Sorry, this referral cannot be completed. The referrer " + "currently has an outstanding balance. Please contact " + "customer support" ); // transaction will roll back if Complete() not called } } }