我强烈建议您先阅读有关反应式编程概念的指南或教程,然后再继续下一步。大多数指南和教程都涵盖了 RxJS(Reactive Extensions for JavaScript,在 Angular 决定使用 Observable<Response> 而不是 Promise<Response> 作为其内置 HTTP 客户端库之后填充。虽然许多指南涵盖 RxJS,但它们完全适用于 Reactive为其他平台编程,例如 .NET(虽然 IObservable<T> 是 .NET Framework 的一部分,但您需要单独的 Reactive Extensions 库才能正确地进行响应式编程,而无需重新发明轮子)。
重要提示:Reactive Extensions, RxJS and Reactive programming have absolutely nothing to do with "React"/"ReactJS" and the React-pattern(有切线关系,但它们是完全不同的东西)。
资源:
至于你的情况,这是我的建议:
如果class Manager 必须是可变的:
- 删除
public IObservable<bool> IsEnabled { get; set; }
- 定义一个新的不可变
class ManagerState。
- 扩展
class Manager : IObservable<ManagerState>
- 每当
class Manager 中的可变属性发生更改时,都会向订阅者发送一个新的ManagerState(填充Manager 的快照副本)。
如果class Manager 可以设为不可变:
- 删除
public IObservable<bool> IsEnabled { get; set; }
- 定义一个实现
IObservable<Manager>的新类ManagerSource
- 每次
Manager 以某种方式更新时,都会向订阅者发送一个新的Manager 对象(填充Manager 的快照副本)。
示例(当class Manager 可变时):
class Manager : IObservable<ManagerState>
{
private Boolean isEnabled; // backing field
public Boolean IsEnabled
{
get { return this.isEnabled; }
set
{
this.isEnabled = value;
this.NotifySubscribers();
}
}
private Boolean isActive; // backing field
public Boolean IsActive
{
get { return this.isActive; }
set
{
this.isActive = value;
this.NotifySubscribers();
}
}
#region Observers (Subscribers) handling:
private readonly ConcurrentBag<IObserver<ManagerState>> subscribers = new ConcurrentBag<IObserver<ManagerState>>();
private void NotifySubscribers()
{
ManagerState snapshot = new ManagerState(
this.IsEnabled,
this.IsActive,
// etc
);
foreach( IObserver<ManagerState> observer in this.subscribers )
{
observer.OnNext( snapshot );
}
}
#endregion
}
// Represents a snapshot of the state of a `Manager`
class ManagerState
{
public ManagerState( Boolean isEnabled, Boolean isActive )
{
this.IsEnabled = isEnabled;
this.IsActive = isActive;
}
public Boolean IsEnabled { get; }
public Boolean IsActive { get; }
// any other members, etc
}
请注意,这可以与对INotifyPropertyChanged 的支持结合使用(尽管我认为这是一个坏主意,因为支持多种方式来完成同一件事最终会使您的用户感到困惑/消费者/同事)——有点像System.Net.Sockets.Socket 有Accept、AcceptAsync、BeginAccept/EndAccept,因为它支持同步,以及 APM 和 EAP 异步范式(但由于某种原因不支持 TPL)。
class Manager : IObservable<ManagerState>, INotifyPropertyChanged
{
private Boolean isEnabled; // backing field
public Boolean IsEnabled
{
get { return this.isEnabled; }
set
{
this.isEnabled = value;
this.OnPropertyChanged( nameof(this.IsEnabled) );
}
}
private Boolean isActive; // backing field
public Boolean IsActive
{
get { return this.isActive; }
set
{
this.isActive = value;
this.OnPropertyChanged( nameof(this.IsActive) );
}
}
#region INotifyPropetyChanged and Observers (Subscribers) handling:
private readonly ConcurrentBag<IObserver<ManagerState>> subscribers = new ConcurrentBag<IObserver<ManagerState>>();
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged( String name )
{
// First, notify users of INotifyPropetyChanged:
this.PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( name ) );
// Then notify users of IObservable:
ManagerState snapshot = new ManagerState(
this.IsEnabled,
this.IsActive,
// etc
);
foreach( IObserver<ManagerState> observer in this.subscribers )
{
observer.OnNext( snapshot );
}
}
#endregion
}