Skip to main content
Code Review

Return to Question

Notice removed Draw attention by Community Bot
Bounty Ended with JanDotNet's answer chosen by Community Bot
edited tags
Link
t3chb0t
  • 44.7k
  • 9
  • 84
  • 190
Tweeted twitter.com/StackCodeReview/status/886499165148033024
Notice added Draw attention by Amit Raz
Bounty Started worth 100 reputation by Amit Raz
Fix a couple of indents
Source Link
Stephen Rauch
  • 4.3k
  • 12
  • 24
  • 36
namespace StocksApp
{ namespace StocksApp public class ServerModule : Nancy.NancyModule
 {
 public ServerModule()
 {
 public class ServerModule : Nancy Post["/User/{id}"] = parameters => CreateUser(parameters);
 Get["/UserShares/{id}"] = parameters => GetUserShares(parameters);
 Post["/AddShareToUser/{id}/{share}"] = parameters => RegisterUserToShare(parameters);
 Post["/AddShareToRepository/{id}"] = parameters => AddShareToRepository(parameters);
 }
 private dynamic AddShareToRepository(dynamic parameters)
 {
 string id = parameters["id"].NancyModuleToString();
 if (!string.IsNullOrEmpty(id))
 {
 publicif ServerModule(!RepositoriesFactory.StocksRepository.AddStock(id))
 {
 Post["/User/{id}"] = parameters =>return CreateUserJsonConvert.SerializeObject(parameters);
 Get["/UserShares/{id}"] = parameters =>new GetUserSharesSimpleResponse(parameters);
  Post["/AddShareToUser/{id}/{share}"] = parameters => RegisterUserToShare(parameters);
  Post["/AddShareToRepository/{id}"]IsSuccess = parameters =>false AddShareToRepository(parameters});
 }
 return JsonConvert.SerializeObject(new SimpleResponse() { IsSuccess = true });
 }
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = "Id null"
 });
  }
 private static dynamic AddShareToRepositoryRegisterUserToShare(dynamic parameters)
 {
 try
 {
 string id = parameters["id"].ToString();
 if (!string.IsNullOrEmpty(id))
 {
 stringUser iduser = parameters["id"]RepositoriesFactory.ToStringUsersRepository.GetUser(id);
 if (!stringuser.IsNullOrEmptyRegisterToStockUpdated(idparameters["share"]))
 {
 if (!RepositoriesFactory.StocksRepository.AddStock(id))
 {
 return JsonConvert.SerializeObject(new SimpleResponse() { IsSuccess = false });
 }
 return JsonConvert.SerializeObject(new SimpleResponse() { IsSuccess = true });
 }
 return JsonConvert.SerializeObject(new SimpleResponse() { IsSuccess = false, Message = "Id null"
 "Could not register user" });
 }
 private static dynamicreturn RegisterUserToShareJsonConvert.SerializeObject(dynamicnew parameters)SimpleResponse
 {
 try
 {
 string id = parameters["id"].ToString();
 if (!string.IsNullOrEmpty(id))
 {
 User user = RepositoriesFactory.UsersRepository.GetUser(id);
 if (user.RegisterToStockUpdated(parameters["share"]))
 {
 return JsonConvert.SerializeObject(new SimpleResponse() { IsSuccess = true });
 }
 return JsonConvert.SerializeObject(new SimpleResponse() { IsSuccess = false, Message = "Could not register user" });
 }
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = "Id null"
 });
 }
 catch (Exception e)
 {
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = e.ToString()
 });
 }
 }
 
 private static dynamic GetUserShares(dynamic parameters)
 {
 try
 IsSuccess = {false,
 string idMessage = parameters["id"]e.ToString();
 if (!string.IsNullOrEmpty(id)});
 {}
 User user = RepositoriesFactory.UsersRepository.GetUser(id);}
 string jsonData =
 private static dynamic JsonConvert.SerializeObjectGetUserShares(newdynamic StockListResponseparameters)
 {
 try
 {
 string Stocksid = userparameters["id"].GetUpdatedStocksToString(),
 IsSuccess = true
 });
 return jsonData;
 }
 returnif JsonConvert(!string.SerializeObjectIsNullOrEmpty(new StockListResponseid))
 {
 IsSuccess = false,
 User Messageuser = "Id null"
  }RepositoriesFactory.UsersRepository.GetUser(id);
 }
  catch (Exception e)
  string jsonData {=
 return JsonConvert.SerializeObject(new StockListResponse
 {
 IsSuccessStocks = falseuser.GetUpdatedStocks(),
 MessageIsSuccess = e.ToString()true
 });
 }return jsonData;
 }
 private static dynamicreturn CreateUserJsonConvert.SerializeObject(dynamicnew parameters)StockListResponse
 {
 try
 {
 string idIsSuccess = parameters["id"].ToString();
  if (!string.IsNullOrEmpty(id))false,
 Message = "Id {null"
 RepositoriesFactory.UsersRepository.AddUser(id});
 }
 returncatch JsonConvert.SerializeObject(new SimpleResponse { IsSuccess = trueException }e);
 }{
 return JsonConvert.SerializeObject(new SimpleResponseStockListResponse
 {
 IsSuccess = false,
 Message = "Id null"e.ToString()
 });
 }
 }
 private static catchdynamic CreateUser(Exceptiondynamic eparameters)
 {
 try
 return JsonConvert.SerializeObject(new SimpleResponse{
 string id = {parameters["id"].ToString();
 if (!string.IsNullOrEmpty(id))
 IsSuccess = false,
 {
 Message = eRepositoriesFactory.ToStringUsersRepository.AddUser(id);
 });
  return JsonConvert.SerializeObject(new SimpleResponse { IsSuccess = true });
 }
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = "Id null"
 });
 }
 catch (Exception e)
 {
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = e.ToString()
 });
 }
 }
 }
}
namespace StocksApp
{
 public static class RepositoriesFactory
 {
 public static IUsersRepository UsersRepository { get;}
 public static IStocksRepository StocksRepository{ get; }
 static RepositoriesFactory()
 {
 StocksRepository = new StocksRepository();
 UsersRepository = new UsersRepository(StocksRepository);
 }
 }
}
namespace StocksApp.Repositories
{
 public class StocksRepository : IStocksRepository
 {
 public ConcurrentDictionary<string, Stock> Stocks { get; set; }
 public Stock GetStock(string stockID)
 {
 if (Stocks.ContainsKey(stockID))
 {
 return Stocks[stockID];
 }
 return null;
 }
 public IEnumerable<string> StockList => Stocks.Keys;
 public StocksRepository()
 {
 Stocks = new ConcurrentDictionary<string, Stock>(
 new Dictionary<string, Stock> {
 {"INTC", new Stock("INTC") },
 {"GOOG", new Stock("GOOG") },
 {"MSC", new Stock("MSC") },
 {"AMD", new Stock("AMD") },
 {"AAPL", new Stock("AAPL") }}
 );
 }
 public bool AddStock(string id)
 {
 return Stocks.TryAdd(id, new Stock(id));
 }
 public void StartUpdats()
 {
 Random r = new Random();
 Task.Run(() =>
 {
 while (true)
 {
 int index = r.Next(0, Stocks.Keys.Count);
 double value = Math.Round(r.NextDouble() * 50, 2);
 string stockName = StockList.ElementAt(index);
 Console.WriteLine($"{stockName} was updated to {value}");
 Stocks[stockName].UpdateValue(value);
 Thread.Sleep(500);
 }
 });
 }
 }
}
 namespace StocksApp
 {
 
 
 public class ServerModule : Nancy.NancyModule
 {
 public ServerModule()
 {
 Post["/User/{id}"] = parameters => CreateUser(parameters);
 Get["/UserShares/{id}"] = parameters => GetUserShares(parameters);
  Post["/AddShareToUser/{id}/{share}"] = parameters => RegisterUserToShare(parameters);
  Post["/AddShareToRepository/{id}"] = parameters => AddShareToRepository(parameters);
 }
 
 private dynamic AddShareToRepository(dynamic parameters)
 {
 string id = parameters["id"].ToString();
 if (!string.IsNullOrEmpty(id))
 {
 if (!RepositoriesFactory.StocksRepository.AddStock(id))
 {
 return JsonConvert.SerializeObject(new SimpleResponse() { IsSuccess = false });
 }
 return JsonConvert.SerializeObject(new SimpleResponse() { IsSuccess = true });
 }
 return JsonConvert.SerializeObject(new SimpleResponse { IsSuccess = false, Message = "Id null"
  });
 }
 private static dynamic RegisterUserToShare(dynamic parameters)
 {
 try
 {
 string id = parameters["id"].ToString();
 if (!string.IsNullOrEmpty(id))
 {
 User user = RepositoriesFactory.UsersRepository.GetUser(id);
 if (user.RegisterToStockUpdated(parameters["share"]))
 {
 return JsonConvert.SerializeObject(new SimpleResponse() { IsSuccess = true });
 }
 return JsonConvert.SerializeObject(new SimpleResponse() { IsSuccess = false, Message = "Could not register user" });
 }
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = "Id null"
 });
 }
 catch (Exception e)
 {
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = e.ToString()
 });
 }
 }
 
 private static dynamic GetUserShares(dynamic parameters)
 {
 try
  {
 string id = parameters["id"].ToString();
 if (!string.IsNullOrEmpty(id))
 {
 User user = RepositoriesFactory.UsersRepository.GetUser(id);
 string jsonData =
 JsonConvert.SerializeObject(new StockListResponse
 {
 Stocks = user.GetUpdatedStocks(),
 IsSuccess = true
 });
 return jsonData;
 }
 return JsonConvert.SerializeObject(new StockListResponse
 {
 IsSuccess = false,
  Message = "Id null"
  });
 }
  catch (Exception e)
  {
 return JsonConvert.SerializeObject(new StockListResponse
 {
 IsSuccess = false,
 Message = e.ToString()
 });
 }
 }
 private static dynamic CreateUser(dynamic parameters)
 {
 try
 {
 string id = parameters["id"].ToString();
  if (!string.IsNullOrEmpty(id))
 {
 RepositoriesFactory.UsersRepository.AddUser(id);
 return JsonConvert.SerializeObject(new SimpleResponse { IsSuccess = true });
 }
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = "Id null"
 });
 }
 catch (Exception e)
 {
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = e.ToString()
 });
  }
 }
 }
 }
namespace StocksApp
{
 public static class RepositoriesFactory
 {
 public static IUsersRepository UsersRepository { get;}
 public static IStocksRepository StocksRepository{ get; }
 static RepositoriesFactory()
 {
 StocksRepository = new StocksRepository();
 UsersRepository = new UsersRepository(StocksRepository);
 }
 }
}
namespace StocksApp.Repositories
{
 public class StocksRepository : IStocksRepository
 {
 public ConcurrentDictionary<string, Stock> Stocks { get; set; }
 public Stock GetStock(string stockID)
 {
 if (Stocks.ContainsKey(stockID))
 {
 return Stocks[stockID];
 }
 return null;
 }
 public IEnumerable<string> StockList => Stocks.Keys;
 public StocksRepository()
 {
 Stocks = new ConcurrentDictionary<string, Stock>(
 new Dictionary<string, Stock> {
 {"INTC", new Stock("INTC") },
 {"GOOG", new Stock("GOOG") },
 {"MSC", new Stock("MSC") },
 {"AMD", new Stock("AMD") },
 {"AAPL", new Stock("AAPL") }}
 );
 }
 public bool AddStock(string id)
 {
 return Stocks.TryAdd(id, new Stock(id));
 }
 public void StartUpdats()
 {
 Random r = new Random();
 Task.Run(() =>
 {
 while (true)
 {
 int index = r.Next(0, Stocks.Keys.Count);
 double value = Math.Round(r.NextDouble() * 50, 2);
 string stockName = StockList.ElementAt(index);
 Console.WriteLine($"{stockName} was updated to {value}");
 Stocks[stockName].UpdateValue(value);
 Thread.Sleep(500);
 }
 });
 }
 }
}
namespace StocksApp
{  public class ServerModule : Nancy.NancyModule
 {
 public ServerModule()
 {
  Post["/User/{id}"] = parameters => CreateUser(parameters);
 Get["/UserShares/{id}"] = parameters => GetUserShares(parameters);
 Post["/AddShareToUser/{id}/{share}"] = parameters => RegisterUserToShare(parameters);
 Post["/AddShareToRepository/{id}"] = parameters => AddShareToRepository(parameters);
 }
 private dynamic AddShareToRepository(dynamic parameters)
 {
 string id = parameters["id"].ToString();
 if (!string.IsNullOrEmpty(id))
 {
 if (!RepositoriesFactory.StocksRepository.AddStock(id))
 {
 return JsonConvert.SerializeObject(new SimpleResponse() { IsSuccess = false });
 }
 return JsonConvert.SerializeObject(new SimpleResponse() { IsSuccess = true });
 }
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = "Id null"
 });
  }
 private static dynamic RegisterUserToShare(dynamic parameters)
 {
 try
 {
 string id = parameters["id"].ToString();
 if (!string.IsNullOrEmpty(id))
 {
 User user = RepositoriesFactory.UsersRepository.GetUser(id);
 if (user.RegisterToStockUpdated(parameters["share"]))
 {
 return JsonConvert.SerializeObject(new SimpleResponse() { IsSuccess = true });
 }
 return JsonConvert.SerializeObject(new SimpleResponse() { IsSuccess = false, Message = "Could not register user" });
 }
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = "Id null"
 });
 }
 catch (Exception e)
 {
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = e.ToString()
 });
 }
 }
 private static dynamic GetUserShares(dynamic parameters)
 {
 try
 {
 string id = parameters["id"].ToString();
 if (!string.IsNullOrEmpty(id))
 {
 User user = RepositoriesFactory.UsersRepository.GetUser(id);
 string jsonData =
 JsonConvert.SerializeObject(new StockListResponse
 {
 Stocks = user.GetUpdatedStocks(),
 IsSuccess = true
 });
 return jsonData;
 }
 return JsonConvert.SerializeObject(new StockListResponse
 {
 IsSuccess = false,
 Message = "Id null"
 });
 }
 catch (Exception e)
 {
 return JsonConvert.SerializeObject(new StockListResponse
 {
 IsSuccess = false,
 Message = e.ToString()
 });
 }
 }
 private static dynamic CreateUser(dynamic parameters)
 {
 try
 {
 string id = parameters["id"].ToString();
 if (!string.IsNullOrEmpty(id))
 {
 RepositoriesFactory.UsersRepository.AddUser(id);
 return JsonConvert.SerializeObject(new SimpleResponse { IsSuccess = true });
 }
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = "Id null"
 });
 }
 catch (Exception e)
 {
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = e.ToString()
 });
 }
 }
 }
}
namespace StocksApp
{
 public static class RepositoriesFactory
 {
 public static IUsersRepository UsersRepository { get;}
 public static IStocksRepository StocksRepository{ get; }
 static RepositoriesFactory()
 {
 StocksRepository = new StocksRepository();
 UsersRepository = new UsersRepository(StocksRepository);
 }
 }
}
namespace StocksApp.Repositories
{
 public class StocksRepository : IStocksRepository
 {
 public ConcurrentDictionary<string, Stock> Stocks { get; set; }
 public Stock GetStock(string stockID)
 {
 if (Stocks.ContainsKey(stockID))
 {
 return Stocks[stockID];
 }
 return null;
 }
 public IEnumerable<string> StockList => Stocks.Keys;
 public StocksRepository()
 {
 Stocks = new ConcurrentDictionary<string, Stock>(
 new Dictionary<string, Stock> {
 {"INTC", new Stock("INTC") },
 {"GOOG", new Stock("GOOG") },
 {"MSC", new Stock("MSC") },
 {"AMD", new Stock("AMD") },
 {"AAPL", new Stock("AAPL") }}
 );
 }
 public bool AddStock(string id)
 {
 return Stocks.TryAdd(id, new Stock(id));
 }
 public void StartUpdats()
 {
 Random r = new Random();
 Task.Run(() =>
 {
 while (true)
 {
 int index = r.Next(0, Stocks.Keys.Count);
 double value = Math.Round(r.NextDouble() * 50, 2);
 string stockName = StockList.ElementAt(index);
 Console.WriteLine($"{stockName} was updated to {value}");
 Stocks[stockName].UpdateValue(value);
 Thread.Sleep(500);
 }
 });
 }
 }
}
Source Link

Client Server Stocks application

I was given task to build a client server application, using any technology I want. Here are the requirements

  1. To simplify the process the Server would have an in memory stock list and there would be a random data generator to update the stock data
  2. Each client will have his own stock list
  3. Each client can add stocks to its list
  4. To simplify the process each client will use polling to get the stock prices, but the server needs to return only the changed stocks and no the whole list.
  5. There will be an option to add new stocks to the repository.

I am focusing more on the server side here and for now the client is a console app. each client generates a token (guid) and sends it to the server as his ID. I used Nancy http server as the back end.

I would like you to please comment about the correctness of my implementation as if it was a code review for your team. OOP design, efficient and safe server implementation

I would appreciate any comments or questions.

1.Server Project

ServerModule.cs

 namespace StocksApp
 {
 
 
 public class ServerModule : Nancy.NancyModule
 {
 
 public ServerModule()
 {
 Post["/User/{id}"] = parameters => CreateUser(parameters);
 Get["/UserShares/{id}"] = parameters => GetUserShares(parameters);
 Post["/AddShareToUser/{id}/{share}"] = parameters => RegisterUserToShare(parameters);
 Post["/AddShareToRepository/{id}"] = parameters => AddShareToRepository(parameters);
 }
 
 private dynamic AddShareToRepository(dynamic parameters)
 {
 string id = parameters["id"].ToString();
 if (!string.IsNullOrEmpty(id))
 {
 if (!RepositoriesFactory.StocksRepository.AddStock(id))
 {
 return JsonConvert.SerializeObject(new SimpleResponse() { IsSuccess = false });
 }
 return JsonConvert.SerializeObject(new SimpleResponse() { IsSuccess = true });
 }
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = "Id null"
 });
 }
 
 private static dynamic RegisterUserToShare(dynamic parameters)
 {
 try
 {
 string id = parameters["id"].ToString();
 if (!string.IsNullOrEmpty(id))
 {
 User user = RepositoriesFactory.UsersRepository.GetUser(id);
 if (user.RegisterToStockUpdated(parameters["share"]))
 {
 return JsonConvert.SerializeObject(new SimpleResponse() { IsSuccess = true });
 }
 return JsonConvert.SerializeObject(new SimpleResponse() { IsSuccess = false, Message = "Could not register user" });
 }
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = "Id null"
 });
 }
 catch (Exception e)
 {
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = e.ToString()
 });
 }
 }
 
 private static dynamic GetUserShares(dynamic parameters)
 {
 try
 {
 string id = parameters["id"].ToString();
 if (!string.IsNullOrEmpty(id))
 {
 User user = RepositoriesFactory.UsersRepository.GetUser(id);
 string jsonData =
 JsonConvert.SerializeObject(new StockListResponse
 {
 Stocks = user.GetUpdatedStocks(),
 IsSuccess = true
 });
 return jsonData;
 }
 return JsonConvert.SerializeObject(new StockListResponse
 {
 IsSuccess = false,
 Message = "Id null"
 });
 }
 catch (Exception e)
 {
 return JsonConvert.SerializeObject(new StockListResponse
 {
 IsSuccess = false,
 Message = e.ToString()
 });
 }
 }
 
 private static dynamic CreateUser(dynamic parameters)
 {
 try
 {
 string id = parameters["id"].ToString();
 if (!string.IsNullOrEmpty(id))
 {
 RepositoriesFactory.UsersRepository.AddUser(id);
 return JsonConvert.SerializeObject(new SimpleResponse { IsSuccess = true });
 }
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = "Id null"
 });
 }
 catch (Exception e)
 {
 return JsonConvert.SerializeObject(new SimpleResponse
 {
 IsSuccess = false,
 Message = e.ToString()
 });
 }
 }
 }
 }

RepositoriesFactory.cs

 namespace StocksApp
{
 public static class RepositoriesFactory
 {
 public static IUsersRepository UsersRepository { get;}
 public static IStocksRepository StocksRepository{ get; }
 static RepositoriesFactory()
 {
 StocksRepository = new StocksRepository();
 UsersRepository = new UsersRepository(StocksRepository);
 }
 }
}

IStocksRepository

namespace StocksApp.Repositories
{
 public interface IStocksRepository
 {
 void StartUpdats();
 IEnumerable<string> StockList { get; }
 Stock GetStock(string stockID);
 bool AddStock(string id);
 }
}

StocksRepository.cs

 namespace StocksApp.Repositories
{
 public class StocksRepository : IStocksRepository
 {
 public ConcurrentDictionary<string, Stock> Stocks { get; set; }
 public Stock GetStock(string stockID)
 {
 if (Stocks.ContainsKey(stockID))
 {
 return Stocks[stockID];
 }
 return null;
 }
 public IEnumerable<string> StockList => Stocks.Keys;
 public StocksRepository()
 {
 Stocks = new ConcurrentDictionary<string, Stock>(
 new Dictionary<string, Stock> {
 {"INTC", new Stock("INTC") },
 {"GOOG", new Stock("GOOG") },
 {"MSC", new Stock("MSC") },
 {"AMD", new Stock("AMD") },
 {"AAPL", new Stock("AAPL") }}
 );
 }
 public bool AddStock(string id)
 {
 return Stocks.TryAdd(id, new Stock(id));
 }
 public void StartUpdats()
 {
 Random r = new Random();
 Task.Run(() =>
 {
 while (true)
 {
 int index = r.Next(0, Stocks.Keys.Count);
 double value = Math.Round(r.NextDouble() * 50, 2);
 string stockName = StockList.ElementAt(index);
 Console.WriteLine($"{stockName} was updated to {value}");
 Stocks[stockName].UpdateValue(value);
 Thread.Sleep(500);
 }
 });
 }
 }
}

IUsersRepository.cs

namespace StocksApp.Repositories
{
 public interface IUsersRepository
 {
 void AddUser(string id);
 User GetUser(string id);
 void RegisterForUpdated(string userID, string stockID);
 }
}

UsersRepository.cs

namespace StocksApp.Repositories
{
 public class UsersRepository : IUsersRepository
 {
 private readonly IStocksRepository _stockRepository;
 private Dictionary<string, User> _users = new Dictionary<string, User>();
 public UsersRepository(IStocksRepository stockRepository)
 {
 _stockRepository = stockRepository;
 }
 public void AddUser(string id)
 {
 _users[id] = new User("id",_stockRepository);
 }
 public User GetUser(string id)
 {
 if (_users.ContainsKey(id))
 {
 return _users[id];
 }
 return null;
 }
 public void RegisterForUpdated(string userID, string stockID)
 {
 if (_users.ContainsKey(userID))
 {
 _users[userID].RegisterToStockUpdated(stockID);
 }
 }
 }
}

User.cs

namespace StocksApp.Repositories
{
 public class User
 {
 private readonly IStocksRepository _stockRepository;
 private readonly ConcurrentDictionary<string,Stock> _registeredStocks = new ConcurrentDictionary<string,Stock>();
 private readonly IDictionary<string, double> _changedStocks = new Dictionary<string, double>();
 private readonly object _locker = new object();
 public string ID { get; }
 public User(string id, IStocksRepository stockRepository)
 {
 _stockRepository = stockRepository;
 ID = id;
 }
 public bool RegisterToStockUpdated(string stockID)
 {
 //so we dont register twice.
 if (_registeredStocks.ContainsKey(stockID))
 {
 return false;
 }
 Stock stock = _stockRepository.GetStock(stockID);
 if (stock != null)
 {
 stock.Updated += Stock_Updated;
 _registeredStocks.TryAdd(stockID,stock);
 return true;
 }
 return false;
 }
 private void Stock_Updated(Stock stock)
 {
 lock (_locker)
 {
 _changedStocks[stock.Name] = stock.Value;
 }
 }
 public IDictionary<string, double> GetUpdatedStocks()
 {
 IDictionary<string, double> returnValue;
 lock (_locker)
 {
 returnValue = new Dictionary<string, double>(_changedStocks);
 _changedStocks.Clear();
 }
 return returnValue;
 }
 }
}

there is also the bootstrapper for the console server application

Program.cs

namespace StocksApp
{
 class Program
 {
 private readonly IStocksRepository _stocksRepository;
 private readonly IUsersRepository _usersRepository;
 private string _url = "http://localhost";
 private int _port = 8080;
 private NancyHost _nancy;
 public Program(IStocksRepository stocksRepository, IUsersRepository usersRepository)
 {
 _stocksRepository = stocksRepository;
 _usersRepository = usersRepository;
 var uri = new Uri($"{_url}:{_port}/");
 var configuration = new HostConfiguration()
 {
 UrlReservations = new UrlReservations() { CreateAutomatically = true }
 };
 _nancy = new NancyHost(configuration,uri);
 }
 private void Start()
 {
 _nancy.Start();
 _stocksRepository.StartUpdats();
 Console.WriteLine($"Started listennig port {_port}");
 Console.ReadKey();
 _nancy.Stop();
 
 }
 static void Main(string[] args)
 {
 var p = new Program(RepositoriesFactory.StocksRepository, RepositoriesFactory.UsersRepository);
 p.Start();
 }
 }
}

2. SharedProject

Stock.cs

namespace StoksApp.Shared.Entities
{
 public class Stock
 {
 public string Name { get; set; }
 public double Value { get; set; }
 public event Action<Stock> Updated = delegate { };
 public Stock(string name)
 {
 Name = name;
 }
 public void UpdateValue(double value)
 {
 Value = value;
 Updated(this);
 }
 }
}

SimpleResponse.cs

namespace StoksApp.Shared.Entities
{
 public class SimpleResponse
 {
 public bool IsSuccess { get; set; }
 public string Message { get; set; }
 }
}

StockListResponse.cs

namespace StoksApp.Shared.Entities
{
 public class StockListResponse : SimpleResponse
 {
 public IDictionary<string, double> Stocks { get; set; }
 }
}
lang-cs

AltStyle によって変換されたページ (->オリジナル) /