IConfiguration vs IOptions NET
Synchronous and Asynchronous in .NET Core
Model Binding and Validation in ASP.NET Core
ControllerBase vs Controller in ASP.NET Core
ConfigureServices and Configure methods
IHostedService interface in .NET Core
ASP.NET Core request processing
| Command-Pattern :👈 | 👉:Template-Method-Pattern |
Observer Pattern in C# |
The Observer Pattern is a behavioral design pattern where an object (called the Subject) maintains a list of dependents (called Observers) and notifies them automatically of any state changes.
In modern C#, this concept is often implemented using events, delegates, or Reactive Extensions (Rx) for reactive state binding.
Letβs build a simple Stock Price Tracker using the Observer Pattern.
using System;
using System.Collections.Generic;
// Observer Interface
public interface IObserver
{
void Update(decimal price);
}
// Subject Interface
public interface ISubject
{
void Attach(IObserver observer);
void Detach(IObserver observer);
void Notify();
}
// Concrete Subject
public class Stock : ISubject
{
private List<IObserver> _observers = new List<IObserver>();
private decimal _price;
public decimal Price
{
get => _price;
set
{
_price = value;
Notify(); // Notify observers when price changes
}
}
public void Attach(IObserver observer)
{
_observers.Add(observer);
}
public void Detach(IObserver observer)
{
_observers.Remove(observer);
}
public void Notify()
{
foreach (var observer in _observers)
{
observer.Update(_price);
}
}
}
// Concrete Observers
public class MobileApp : IObserver
{
public void Update(decimal price)
{
Console.WriteLine($"[MobileApp] Stock price updated: {price}");
}
}
public class WebApp : IObserver
{
public void Update(decimal price)
{
Console.WriteLine($"[WebApp] Stock price updated: {price}");
}
}
// Client
class Program
{
static void Main(string[] args)
{
Stock stock = new Stock();
IObserver mobileApp = new MobileApp();
IObserver webApp = new WebApp();
stock.Attach(mobileApp);
stock.Attach(webApp);
// Change stock price
stock.Price = 100.50m;
stock.Price = 102.75m;
// Detach one observer
stock.Detach(webApp);
stock.Price = 105.00m;
}
}
[MobileApp] Stock price updated: 100.50 [WebApp] Stock price updated: 100.50 [MobileApp] Stock price updated: 102.75 [WebApp] Stock price updated: 102.75 [MobileApp] Stock price updated: 105.00
Instead of manually implementing the pattern, C# provides events and Reactive Extensions (Rx):
using System;
using System.Reactive.Subjects;
class Program
{
static void Main()
{
var stockPrice = new BehaviorSubject<decimal>(0);
// Observers subscribe
stockPrice.Subscribe(price => Console.WriteLine($"[MobileApp] Price: {price}"));
stockPrice.Subscribe(price => Console.WriteLine($"[WebApp] Price: {price}"));
// State changes
stockPrice.OnNext(100.50m);
stockPrice.OnNext(102.75m);
}
}
| Command-Pattern :👈 | 👉:Template-Method-Pattern |