Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Your team is developing VisageTome, a social media platform to rival the greates

ID: 3920149 • Letter: Y

Question

Your team is developing VisageTome, a social media platform to rival the greatest systems of the day. The project is off to a good start, but your manager now wants you to add notifications to the system; specifically, she wants users to be able to follow one another and receive a message when the followed user's status changes. Add an event to the User class and use it to wire up these notifications.

The system begins by executing a list of commands from a document before allowing the user to input commands.

VisageTome.cs

using System;

using System.IO;

using System.Collections.Generic;

class VisageTome

{

#region Main

private static Dictionary<string, User> users = new Dictionary<string, User>();

static void Main()

{

Console.WriteLine("Welcome to VisageTome!");

Console.WriteLine("Executing from file...");

foreach(string line in File.ReadAllLines("commands.txt"))

{

Console.WriteLine(" > {0}", line);

ProcessCommand(line);

}

Console.WriteLine(" Executing from user...");

bool continue_user_input = true;

while(continue_user_input)

{

Console.Write(" > ");

string command = Console.ReadLine();

continue_user_input = ProcessCommand(command);

}

}

static bool ProcessCommand(string command)

{

string[] command_split = command.Split(' ');

if(command_split.Length >= 1)

{

if(command_split[0] == "user")

{

if(command_split.Length >= 2)

{

string new_user = command_split[1];

if(users.ContainsKey(new_user))

{

Console.WriteLine("User {0} already exists.", new_user);

}

else

{

users.Add(new_user, new User(new_user));

Console.WriteLine("User {0} added.", new_user);

}

}

else

{

Console.WriteLine("Usage: user <username>");

}

}

else if(command_split[0] == "list")

{

Console.WriteLine("Users:");

foreach(User user in users.Values)

{

Console.WriteLine(" {0}: {1}", user.Name, user.Status);

}

}

else if(command_split[0] == "status")

{

if(command_split.Length >= 3)

{

string user = command_split[1];

if(users.ContainsKey(user))

{

string status = command.Replace("status "+user+" ", "");

Console.WriteLine("User {0} status changing to "{1}".", user, status);

users[user].Status = status;

}

else

{

Console.WriteLine("User {0} does not exist.", user);

}

}

else

{

Console.WriteLine("Usage: status <username> <new status>");

}

}

else if(command_split[0] == "follow")

{

if(command_split.Length >= 3)

{

string follower = command_split[1];

string target = command_split[2];

if(users.ContainsKey(follower) && users.ContainsKey(target))

{

users[follower].FollowUser(users[target]);

Console.WriteLine("User {0} now following user {1}.", follower, target);

}

else

{

Console.WriteLine("User {0} and/or user {1} not found.", follower, target);

}

}

else

{

Console.WriteLine("Usage: follow <follower> <target>");

}

}

else if(command_split[0] == "unfollow")

{

if(command_split.Length >= 3)

{

string follower = command_split[1];

string target = command_split[2];

if(users.ContainsKey(follower) && users.ContainsKey(target))

{

users[follower].UnfollowUser(users[target]);

Console.WriteLine("User {0} no longer following user {1}.", follower, target);

}

else

{

Console.WriteLine("User {0} and/or user {1} not found.", follower, target);

}

}

else

{

Console.WriteLine("Usage: unfollow <follower> <target>");

}

}

else if(command_split[0] == "quit")

{

return false;

}

else

{

Console.WriteLine("Usage: <command> [command_args]");

Console.WriteLine("Valid commands: user list status follow unfollow quit");

}

}

else

{

Console.WriteLine("Usage: <command> [command_args]");

Console.WriteLine("Valid commands: user status follow unfollow quit");

}

return true;

}

#endregion

#region User Class

class User

{

private string name;

public string Name { get { return name;} }

private string status;

public string Status

{

get { return status; }

set

{

if(value != status)

{

status = value;

//TODO: Invoke an event that notifies subscribers that this user's status has changed

}

}

}

//TODO: Declare an EventHandler delegate to handle subscribers

public User(string name)

{

this.name = name;

status = "(No status yet)";

}

public void FollowUser(User other)

{

//TODO: Let this user subscribe to the status changed event of the other user;

// be sure to keep the subscriber from subscribing multiple times

}

public void UnfollowUser(User other)

{

//TODO: Let this user unsubscribe from the status changed event of the other user

}

private void ReceiveStatusChanged(object sender, StatusChangedEventArgs e)

{

//In a full application, this might involve sending an email or a pop-up to this user

Console.WriteLine(" {0} has been notified that {1}'s status has just changed to "{2}".", Name, e.Name, e.NewStatus);

}

//TODO: Properly finish the StatusChangedEventArgs class (see ReceiveStatusChanged for a use example)

public class StatusChangedEventArgs : EventArgs

{

}

}

#endregion

}

Explanation / Answer

Hi Programmer,

I have completed the program as mentioned. I have used custom event accessors to prevent user from over subscribing. I have ran the program and it runs fine. You can directly copy the code to a program in visual studio and run.

If my answer satisfies all your requirements please upvote it. Thanks in advance.

Below is the entire program,

using System;
using System.IO;
using System.Collections.Generic;

namespace Chegg_StatusNotification
{
class VisageTome
{
#region Main

private static Dictionary<string, User> users = new Dictionary<string, User>();

static void Main()
{
Console.WriteLine("Welcome to VisageTome!");
Console.WriteLine("Executing from file...");
foreach (string line in File.ReadAllLines("commands.txt"))
{
Console.WriteLine(" > {0}", line);
ProcessCommand(line);
}

Console.WriteLine(" Executing from user...");
bool continue_user_input = true;
while (continue_user_input)
{
Console.Write(" > ");
string command = Console.ReadLine();
continue_user_input = ProcessCommand(command);
}
}

static bool ProcessCommand(string command)
{
string[] command_split = command.Split(' ');

if (command_split.Length >= 1)
{
if (command_split[0] == "user")
{
if (command_split.Length >= 2)
{
string new_user = command_split[1];
if (users.ContainsKey(new_user))
{
Console.WriteLine("User {0} already exists.", new_user);
}
else
{
users.Add(new_user, new User(new_user));
Console.WriteLine("User {0} added.", new_user);
}
}
else
{
Console.WriteLine("Usage: user <username>");
}
}

else if (command_split[0] == "list")
{
Console.WriteLine("Users:");
foreach (User user in users.Values)
{
Console.WriteLine(" {0}: {1}", user.Name, user.Status);
}
}

else if (command_split[0] == "status")
{
if (command_split.Length >= 3)
{
string user = command_split[1];

if (users.ContainsKey(user))
{
string status = command.Replace("status " + user + " ", "");
Console.WriteLine("User {0} status changing to "{1}".", user, status);
users[user].Status = status;
}
else
{
Console.WriteLine("User {0} does not exist.", user);
}
}
else
{
Console.WriteLine("Usage: status <username> <new status>");
}
}

else if (command_split[0] == "follow")
{
if (command_split.Length >= 3)
{
string follower = command_split[1];
string target = command_split[2];
if (users.ContainsKey(follower) && users.ContainsKey(target))
{
users[follower].FollowUser(users[target]);
Console.WriteLine("User {0} now following user {1}.", follower, target);
}
else
{
Console.WriteLine("User {0} and/or user {1} not found.", follower, target);
}
}
else
{
Console.WriteLine("Usage: follow <follower> <target>");
}
}
else if (command_split[0] == "unfollow")
{
if (command_split.Length >= 3)
{
string follower = command_split[1];
string target = command_split[2];

if (users.ContainsKey(follower) && users.ContainsKey(target))
{
users[follower].UnfollowUser(users[target]);
Console.WriteLine("User {0} no longer following user {1}.", follower, target);
}
else
{
Console.WriteLine("User {0} and/or user {1} not found.", follower, target);
}
}
else
{
Console.WriteLine("Usage: unfollow <follower> <target>");
}
}
else if (command_split[0] == "quit")
{
return false;
}
else
{
Console.WriteLine("Usage: <command> [command_args]");
Console.WriteLine("Valid commands: user list status follow unfollow quit");
}
}
else
{
Console.WriteLine("Usage: <command> [command_args]");
Console.WriteLine("Valid commands: user status follow unfollow quit");
}

return true;
}

#endregion

#region User Class

class User
{
private string name;
public string Name { get { return name; } }
private string status;

//TODO: Declare an EventHandler delegate to handle subscribers
private EventHandler<StatusChangedEventArgs> statusChanged;

public event EventHandler<StatusChangedEventArgs> StatusChanged
{
add
{
if (statusChanged == null || !DoesEventSubscriberExist(value))
{
statusChanged += value;
}
}
remove { statusChanged -= value; }
}

private bool DoesEventSubscriberExist(EventHandler<StatusChangedEventArgs> Subscriber)
{
bool exists = false;
foreach(var subscription in statusChanged.GetInvocationList())
{
if (subscription.Equals(Subscriber))
{
exists = true;
break;
}
}

return exists;
}

public string Status
{
get { return status; }
set
{
if (value != status)
{
status = value;
//TODO: Invoke an event that notifies subscribers that this user's status has changed
if (statusChanged != null)
{
statusChanged(this, new StatusChangedEventArgs(name, status));
}
}
}
}

public User(string name)
{
this.name = name;
status = "(No status yet)";
}

public void FollowUser(User other)
{
//TODO: Let this user subscribe to the status changed event of the other user;
other.StatusChanged += ReceiveStatusChanged;
// be sure to keep the subscriber from subscribing multiple times
}

public void UnfollowUser(User other)
{
//TODO: Let this user unsubscribe from the status changed event of the other user
other.StatusChanged -= ReceiveStatusChanged;
}

private void ReceiveStatusChanged(object sender, StatusChangedEventArgs e)
{
//In a full application, this might involve sending an email or a pop-up to this user
Console.WriteLine(" {0} has been notified that {1}'s status has just changed to "{2}".", Name, e.Name, e.NewStatus);
}

//TODO: Properly finish the StatusChangedEventArgs class (see ReceiveStatusChanged for a use example)
public class StatusChangedEventArgs : EventArgs
{
public readonly string Name;
public readonly string NewStatus;
public StatusChangedEventArgs(string name, string newStatus)
{
Name = name; NewStatus = newStatus;
}
}
}

#endregion
}
}