WEBSITE

ASP.NET 3.5 Social Networking : Messaging (part 3) - Implementing the services/application layer

2/16/2013 8:25:02 PM

3.3 Implementing the services/application layer

Once all the repositories are built for single serving, we can begin to create the services layer. Again, this layer is responsible for assembling aggregates and performing complex actions with our entities.

  • MessageService

  • Email

  • AlertService

  • FriendService

MessageService

The MessageService will help us in one way — sending messages. Keep in mind that to send a message, we will need to create a Message, then create a MessageRecipient for the sender's copy, and then create one-to-many MessageRecipients for the receivers of the message. While this is not a complex task really, it is a very appropriate series of tasks for a service object!

//Core/Impl/MessageService.cs
public void SendMessage(string Body, string Subject, string[] To)
{
Message m = new Message();
m.Body = Body;
m.Subject = Subject;
m.CreateDate = DateTime.Now;
m.MessageTypeID = (int)MessageTypes.Message;
m.SentByAccountID = _userSession.CurrentUser.AccountID;
Int64 messageID = _messageRepository.SaveMessage(m);
//create a copy in the sent items folder for this user
MessageRecipient sendermr = new MessageRecipient();
sendermr.AccountID = _userSession.CurrentUser.AccountID;
sendermr.MessageFolderID = (int) MessageFolders.Sent;
sendermr.MessageRecipientTypeID = (int) MessageRecipientTypes.TO;
sendermr.MessageID = messageID;
sendermr.MessageStatusTypeID = (int)MessageStatusTypes.Unread;
_messageRecipientRepository.SaveMessageRecipient(sendermr);
//send to people in the To field
foreach (string s in To)
{
Account toAccount = null;
if (s.Contains("@"))
toAccount = _accountRepository.GetAccountByEmail(s);
else
toAccount = _accountRepository.GetAccountByUsername(s);
if(toAccount != null)
{
MessageRecipient mr = new MessageRecipient();
mr.AccountID = toAccount.AccountID;
mr.MessageFolderID = (int)MessageFolders.Inbox;
mr.MessageID = messageID;
mr.MessageRecipientTypeID = (int) MessageRecipientTypes.TO;
_messageRecipientRepository.SaveMessageRecipient(mr);
_email.SendNewMessageNotification(_userSession. CurrentUser,toAccount.Email);
}
}
}



					  

This should be very straightforward to follow. The first thing we do is to spin up a new instance of the Message that we are sending. We then save it via the MessageRepository and get back the new MessageID to work with down the line.

The next task is to make sure that we paste a copy of the message in the sender's Sent Items folder. We do this by creating a MessageRecipient object and tying it to the sender's account. You will notice that we have assigned it to the Sent Items folder using an enum named MessageFolders, which has IDs that map to the MessageFolders lookup table. This enum is stored next to a new domain object named MessageFolder and looks like this:

//Core/Domain/MessageFolder.cs
namespace Fisharoo.FisharooCore.Core.Domain
{
public enum MessageFolders
{
Inbox = 1,
Sent = 2,
Trash = 3,
Spam = 4
}
public partial class MessageFolder
{
}
}

The next item in the MessageService is assigning the MessageRecipientTypeID to the sender's copy. The MessageRecipientType is to let the display know whether to show the MessageRecipient as a TO, CC, or BCC recipient. This is another enum value that maps back to a lookup table in the database and looks like this:

//Core/Domain/MessageRecipientType.cs
namespace Fisharoo.FisharooCore.Core.Domain
{
public enum MessageRecipientTypes
{
TO = 1,
CC = 2,
BCC = 3
}
public partial class MessageRecipientType
{
}
}

We then move into a foreach loop in the MessageService, which is responsible for determining whether we are looking up a recipient via an email address or a username. It does this by testing the To value of the MessageRecipients to see if it has an ampersand or not, which would correspond to an email address.

Depending on whether the TO value is an email address or a username, we get a copy of an Account object. Once we have a valid Account object to work with, we move on to creating a new MessageRecipient for that Account. You should note that in this implementation of the MessageRecipient, we are placing the Message subscription into the Inbox instead of the Sent Items folder. This MessageRecipient is also of MessageRecipientType TO.

Email

Once the MessageRecipient is successfully created and persisted to the database, we then move on to sending an email notification to the MessageRecipient. The most important thing to note about the additional method of SendNewMessageNotification() is that we are sending a notification — not the whole message!

I mention this because I feel it is important to note that one of the quickest ways to get your sites' IP addresses banned is to be determined to be a sender of spam. Since you are entirely responsible for the content that go out in your messages, you can't directly control what your users type in a message. So don't risk your reputation by sending the entire contents of their messages!


public void SendNewMessageNotification(Account sender, string ToEmail)
{
foreach (string s in ToEmail.Split(new char[] {',',';'}))
{
string message = sender.FirstName + " " + sender.LastName +
" has sent you a message on " + _configuration.SiteName + "! Please log in at " + _configuration.SiteName +
" to view the message.<HR>";
SendEmail(s, "", "", sender.FirstName + " " + sender.LastName +
" has sent you a message on " +
_configuration.SiteName + "!", message);
}
}


					  

This method breaks down all the TO recipients and creates a new email notification using our existing subsystem telling the recipients that they have a new message waiting for them in their Inbox.

AlertService

We will now create these tools, so that we can fill this placeholder out.

//TODO: MESSAGING - point to send message URL
private string GetSendMessageUrl(Int32 AccountID)
{
return "<a href=\"[rootUrl]/mail/newmessage.aspx?AccountID=" + AccountID.ToString() + "\">Click here to send message</a>";
}


					  

This method is simply responsible for creating a link to the new message page passing in the user you want to send a message to. This method is already called from several of our existing AlertService methods.

FriendService

We now need to extend our FriendService.CreateFriendFromFriendInvitation() method. Remember that this method is responsible for creating a friend from an accepted invitation. We now want to add some logic to this that when a friend request is accepted, we send a new Message to the creator of that friend request letting them know that their request was accepted.

public void CreateFriendFromFriendInvitation(Guid InvitationKey, Account InvitationTo)
{
...
//add a message to the inbox regarding the new friendship!
Message m = new Message();
m.Subject = "You and " + InvitationTo.Username + " are now friends!";
m.Body = "You and <a href=\"" + _webContext.RootUrl + InvitationTo.Username + "\">" + InvitationTo.Username + "</a> are
now friends!";
m.CreateDate = DateTime.Now;
m.MessageTypeID = (int)MessageTypes.FriendConfirm;
m.SentByAccountID = InvitationFrom.AccountID;
Int64 messageID = _messageRepository.SaveMessage(m);
MessageRecipient mr = new MessageRecipient();
mr.AccountID = InvitationTo.AccountID;
mr.MessageFolderID = (int)MessageFolders.Inbox;
mr.MessageID = messageID;
mr.MessageRecipientTypeID = (int) MessageRecipientTypes.TO;
mr.MessageStatusTypeID = (int) MessageStatusTypes.Unread;
_messageRecipientRepository.SaveMessageRecipient(mr);
}


					  

This additional code is going through the motions of creating a new message and a recipient for that message. In this case though, we are giving this message the MessageTypeID of MessageTypes.FriendConfirm (or a friend confirmation). Other than that, this code is straightforward.

Other  
 
Top 10
Review : Sigma 24mm f/1.4 DG HSM Art
Review : Canon EF11-24mm f/4L USM
Review : Creative Sound Blaster Roar 2
Review : Philips Fidelio M2L
Review : Alienware 17 - Dell's Alienware laptops
Review Smartwatch : Wellograph
Review : Xiaomi Redmi 2
Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
REVIEW
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
VIDEO TUTORIAL
- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
Popular Tags
Video Tutorail Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Exchange Server Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe Photoshop CorelDRAW X5 CorelDraw 10 windows Phone 7 windows Phone 8 Iphone