مدیریت حالت در برنامههای Blazor توسط الگوی Observer - قسمت دوم
نویسنده: وحید نصیری
تاریخ: ۱۴۰۰/۰۱/۱۸ ۱۵:۱۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
namespace BlazorStateManagement.Stores
{
public interface IAction
{
public string Name { get; }
}
} namespace BlazorStateManagement.Stores.CounterStore
{
public class IncrementAction : IAction
{
public const string Increment = nameof(Increment);
public string Name { get; } = Increment;
}
public class DecrementAction : IAction
{
public const string Decrement = nameof(Decrement);
public string Name { get; } = Decrement;
}
} using System;
namespace BlazorStateManagement.Stores
{
public interface IActionDispatcher
{
void Dispatch(IAction action);
void Subscribe(Action<IAction> actionHandler);
void Unsubscribe(Action<IAction> actionHandler);
}
public class ActionDispatcher : IActionDispatcher
{
private Action<IAction> _actionHandlers;
public void Subscribe(Action<IAction> actionHandler) => _actionHandlers += actionHandler;
public void Unsubscribe(Action<IAction> actionHandler) => _actionHandlers -= actionHandler;
public void Dispatch(IAction action) => _actionHandlers?.Invoke(action);
}
} namespace BlazorStateManagement.Client
{
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
// ...
builder.Services.AddScoped<IActionDispatcher, ActionDispatcher>();
// ...
}
}
} using System;
namespace BlazorStateManagement.Stores.CounterStore
{
public interface ICounterStore : IDisposable
{
CounterState State { get; }
void AddStateChangeListener(Action listener);
void BroadcastStateChange();
void RemoveStateChangeListener(Action listener);
}
} using System;
namespace BlazorStateManagement.Stores.CounterStore
{
public class CounterStore : ICounterStore
{
private readonly CounterState _state = new();
private bool _isDisposed;
private Action _listeners;
private readonly IActionDispatcher _actionDispatcher;
public CounterStore(IActionDispatcher actionDispatcher)
{
_actionDispatcher = actionDispatcher ?? throw new ArgumentNullException(nameof(actionDispatcher));
_actionDispatcher.Subscribe(HandleActions);
}
private void HandleActions(IAction action)
{
switch (action)
{
case IncrementAction:
IncrementCount();
break;
case DecrementAction:
DecrementCount();
break;
}
}
public CounterState State => _state;
private void IncrementCount()
{
_state.Count++;
BroadcastStateChange();
}
private void DecrementCount()
{
_state.Count--;
BroadcastStateChange();
}
public void AddStateChangeListener(Action listener) => _listeners += listener;
public void RemoveStateChangeListener(Action listener) => _listeners -= listener;
public void BroadcastStateChange() => _listeners.Invoke();
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_isDisposed)
{
try
{
if (disposing)
{
_actionDispatcher.Unsubscribe(HandleActions);
}
}
finally
{
_isDisposed = true;
}
}
}
}
} private void HandleActions(IAction action)
{
switch (action)
{
case IncrementAction:
IncrementCount();
break;
case DecrementAction:
DecrementCount();
break;
}
} @inject ICounterStore CounterStore
@code {
private void IncrementCount()
{
CounterStore.IncrementCount();
} @using BlazorStateManagement.Stores
// ...
@inject IActionDispatcher ActionDispatcher
@code {
private void IncrementCount()
{
ActionDispatcher.Dispatch(new IncrementAction());
}