public class Unsubscriber : IDisposable
{
private readonly List<IObserver<Stock>> _observers;
private readonly IObserver<Stock> _observer;
public Unsubscriber(List<IObserver<Stock>> observers, IObserver<Stock> observer)
{
_observers = observers;
_observer = observer;
}
public void Dispose()
{
if (_observer != null && _observers.Contains(_observer))
{
_observers.Remove(_observer);
}
}
}
public class StockTickerObservable : IObservable<Stock>
{
private readonly List<IObserver<Stock>> _observers;
private Stock _stock;
public StockTickerObservable()
{
_observers = new List<IObserver<Stock>>();
}
public Stock Stock
{
get { return _stock; }
set
{
_stock = value;
this.Notify();
}
}
private void Notify()
{
_observers.ForEach(i =>
{
if (_stock.Price < 0 || _stock.DateRecieved == DateTime.MinValue)
{
i.OnError(new ApplicationException("Invalid stock information"));
}
else
{
i.OnNext(_stock);
}
});
}
public IDisposable Subscribe(IObserver<Stock> observer)
{
if (!_observers.Contains(observer))
{
_observers.Add(observer);
}
return new Unsubscriber(_observers, observer);
}
}
public class TwitterStockObservable : IObserver<Stock>
{
public void OnNext(Stock value)
{
Console.WriteLine("{0} changed with price {1}. Recieved on {2}", value.Symbol, value.Price, value.DateRecieved);
}
public void OnError(Exception error)
{
Console.WriteLine("An error occured: {0}", error.Message);
}
public void OnCompleted()
{
Console.WriteLine("Completed!");
}
}
static void Main(string[] args)
{
// Create the Stock Ticker subject object
var stockTickerObservable = new StockTickerObservable();
// Create the object to observe
var twitterStockObservable = new TwitterStockObservable();
// Subscribe and check for new notifications. This will dispose
// of the object (release the observable) once finished.
using (stockTickerObservable.Subscribe(twitterStockObservable))
{
stockTickerObservable.Stock = new Stock
{
Symbol = "TWTR",
Price = 5000,
DateRecieved = DateTime.Now
};
}
Console.ReadLine();
}
static void Main(string[] args)
{
// Create a reference to the delegate object
var stockTickerDelegate = new StockTickerDelegate();
// Subscribe to the StockTicker event. Using a lambda expression to give the
// event what happens after it has been triggered.
stockTickerDelegate.StockTicker += (s, e) =>
Console.WriteLine("Stock from event. Symbol {0}, price {1}, date recieved {2}",
e.Symbol, e.Price, e.DateRecieved);
// An event has been triggered...
stockTickerDelegate.SetStock(new Stock { Symbol = "TWTR", Price = 500, DateRecieved = DateTime.Now });
Console.ReadLine();
}
public class StockTickerDelegate
{
public event EventHandler<StockTickerEventArgs> StockTicker;
protected virtual void OnNewStock(string symbol, double price, DateTime dateRecieved)
{
if (StockTicker != null)
{
StockTicker(this, new StockTickerEventArgs(symbol, price, dateRecieved));
}
}
public void SetStock(Stock stock)
{
OnNewStock(stock.Symbol, stock.Price, stock.DateRecieved);
}
}
public class StockTickerEventArgs : EventArgs
{
public StockTickerEventArgs(string symbol, double price, DateTime dateRecieved)
{
this.Symbol = symbol;
this.Price = price;
this.DateRecieved = dateRecieved;
}
public DateTime DateRecieved { get; set; }
public double Price { get; set; }
public string Symbol { get; set; }
}
public class StockTicker : ISubject
{
private readonly List<IObserver> _observers;
private Stock _stock;
public StockTicker()
{
_observers = new List<IObserver>();
}
public void Subscribe(IObserver observer)
{
_observers.Add(observer);
}
public void Unsubscribe(IObserver observer)
{
if (_observers.Contains(observer))
{
_observers.Remove(observer);
}
}
public void Notify()
{
_observers.ForEach(i => i.Update());
}
public Stock Stock
{
get { return _stock; }
set
{
_stock = value;
this.Notify();
}
}
}
public class TwitterStock : IObserver
{
private StockTicker _stockData;
private double _price;
private DateTime _dateRecieved;
private string _symbol;
public TwitterStock(StockTicker stockData)
{
_stockData = stockData;
_stockData.Subscribe(this);
}
public void Update()
{
_symbol = _stockData.Stock.Symbol;
_price = _stockData.Stock.Price;
_dateRecieved = _stockData.Stock.DateRecieved;
Display();
}
private void Display()
{
Console.WriteLine("{0} changed with price {1} on {2}.", _symbol, _price, _dateRecieved);
}
}
static void Main(string[] args)
{
// Monitor when specific events occur and react to them
var stockTicker = new StockTicker();
// Create observers, subscribe, and listen for the events of the stock ticker
var twitterStock = new TwitterStock(stockTicker);
// Setting the "Stock" property will trigger a new update and will display to the console.
stockTicker.Stock = new Stock
{
Symbol = "TWTR",
Price = 1000,
DateRecieved = DateTime.Now
};
Console.ReadLine();
}