所以我可能最终会对以下代码提出几个问题,可能是因为我使用的是Subject
,我不确定它是否可以使用。
我很难解释,我不知道为什么,也许我缺乏术语。
我想要做的是有一种可以用它注册几个observable的类型,所以我可以传递这个类型并将所有的observable分组并从中公开一个observable。
所以我的第一个问题我感觉我没有以正确的方式思考问题,我想知道这是否正确还是有更多的反应性问题。这样做的方式?
我的意思是我有这种类型你可以注册observables,同样的类型也会暴露我也可以订阅的单个Observable。
我将尝试使用下面的代码示例解释一下。
因此,SomeTypeWithObservable
可能是会暴露IObservable<SomeEvents>
的众多类型之一
ReactiveTesting
类型是尝试将所有可观察对象组合在一起并公开单个IObservable<SomEvents>
的类型。有RegisterObservable
方法将其发送到内部Subject<IObservable<SomeEvents>>
。构造函数将我想要公开的Observable设置为此主题的SelectMany
。
使用下面的实现,在ReactiveTesting
构造函数中执行SelectMany.Publish.RefCount
,然后使用虚拟订阅启动observable,我注意到如果我没有使用虚拟订阅注册没有使用可观察物。
所以我的第二个问题是代码可以有一个虚拟订阅来启动observable,或者我应该做我在评论中做了什么,我只是从Publish可以连接,然后之后立即连接它,或者它们都是错误的,在这种情况下,有人能指出我正确的方向吗?
我的第三个问题我应该使用某个主题吗?
如果我在订阅之前致电RegisterObservable
,如果我没有将虚拟Subscribe
放入或Connect
,那么我就不会观察任何一个触发事件。
我的第四个问题有人可以解释后者吗?
我有点想,因为它是Publish
和RefCount
,所以在有一个从Observable开始的订阅之前没有什么可做的。
代码
- 已修改 - 要显示我想在ReactiveTesting
enum SomeEvents
{
event1,
event2,
event3,
event4
}
interface ISomeTypeWithObservable
{
IObservable<SomeEvents> SomeObservableEvents { get; }
}
class SomeTypeWithObservable2 : ISomeTypeWithObservable
{
private event EventHandler SpecialEvent;
public SomeTypeWithObservable2()
{
var observableFromSpecialEvent = Observable.FromEventPattern(h => SpecialEvent += h, h => SpecialEvent -= h).Select(x => SomeEvents.event2);
SomeObservableEvents = Observable.Create<SomeEvents>(observer =>
{
return observableFromSpecialEvent.Subscribe(observer);
})
.Publish()
.RefCount();
}
public IObservable<SomeEvents> SomeObservableEvents { get; }
public void TriggerEvent()
{
SpecialEvent.Invoke(this, new EventArgs());
}
}
class SomeTypeWithObservable : ISomeTypeWithObservable
{
private event EventHandler SpecialEvent;
public SomeTypeWithObservable()
{
var observableFromSpecialEvent = Observable.FromEventPattern(h => SpecialEvent += h, h => SpecialEvent -= h).Select(x => SomeEvents.event1);
SomeObservableEvents = Observable.Create<SomeEvents>(observer =>
{
return observableFromSpecialEvent.Subscribe(observer);
})
.Publish()
.RefCount();
}
//Some code in here that will produce things to observe, maybe Observable.FromEventPattern...
public IObservable<SomeEvents> SomeObservableEvents { get; }
public void TriggerEvent()
{
SpecialEvent.Invoke(this, new EventArgs());
}
}
class ReactiveTesting
{
private Subject<IObservable<SomeEvents>> _innerEvents = new Subject<IObservable<SomeEvents>>();
public IObservable<SomeEvents> AllEvents;
public ReactiveTesting()
{
AllEvents = _innerEvents.SelectMany(x => x).Publish().RefCount();
AllEvents.Subscribe(next => { }, exception => { }, () => { });
//This instead of the above??
//var connectableObservable = _innerEvents.SelectMany(x => x).Publish();
//AllEvents = connectableObservable;
//connectableObservable.Connect();
}
public void RegisterObservable(ISomeTypeWithObservable someTypeWithObservable)
{
_innerEvents.OnNext(someTypeWithObservable.SomeObservableEvents);
}
}
class Program
{
static void Main(string[] args)
{
var reactiveTesting = new ReactiveTesting();
var someTypeWithObservable = new SomeTypeWithObservable();
var someTypeWithObservable2 = new SomeTypeWithObservable2();
reactiveTesting.AllEvents.Subscribe(next => Console.WriteLine(string.Format("Subscriber 1 - {0}", next.ToString("G"))));
reactiveTesting.AllEvents.Subscribe(next => Console.WriteLine(string.Format("Subscriber 2 - {0}", next.ToString("G"))));
reactiveTesting.RegisterObservable(someTypeWithObservable);
reactiveTesting.RegisterObservable(someTypeWithObservable2);
someTypeWithObservable.TriggerEvent();
someTypeWithObservable.TriggerEvent();
someTypeWithObservable.TriggerEvent();
someTypeWithObservable2.TriggerEvent();
someTypeWithObservable2.TriggerEvent();
someTypeWithObservable2.TriggerEvent();
Console.WriteLine("Press key...");
Console.ReadLine();
}
}
答案 0 :(得分:0)
所以我的第一个问题是我感觉我没有考虑过的事情 正确的方法,我想知道这是否正确或有更多 &#34;反应&#34;这样做的方式?
在Subject
中使用ReactiveTesting
通常是一个提示,您可以使用一些必要的代码来消除或推进。它可能需要重写一些您周围的代码。在这种情况下,你最终会得到这样的东西:
class ReactiveTesting
{
public IObservable<SomeEvents> AllEvents { get; }
public ReactiveTesting(IObservable<IObservable<SomeEvents>> eventSource)
{
AllEvents = eventSource.Merge().Publish().RefCount();
}
}
class Program
{
public static void Main(string[] args)
{
var someTypeWithObservable = new SomeTypeWithObservable();
var reactiveTesting = new ReactiveTesting(Observable.Return(someTypeWithObservable.SomeObservableEvents));
reactiveTesting.AllEvents.Subscribe(next => Console.WriteLine(string.Format("Subscriber 1 - {0}", next.ToString("G"))));
reactiveTesting.AllEvents.Subscribe(next => Console.WriteLine(string.Format("Subscriber 2 - {0}", next.ToString("G"))));
someTypeWithObservable.TriggerEvent();
someTypeWithObservable.TriggerEvent();
someTypeWithObservable.TriggerEvent();
Console.WriteLine("Press key...");
Console.ReadLine();
}
}
所以我的第二个问题是代码可以进行虚拟订阅 从观察开始,或者我应该做我在下面做的事情 评论我刚刚发布了一个可连接的发布然后连接 它紧接着它,或者它们都是错的,在那种情况下,它可以 有人指出我正确的方向?
没有必要。它对我来说就像删除它一样。虚拟订阅有助于.Replay().Refcount()
。我没有看到.Publish()
的重点。
我的第三个问题我应该使用某个主题吗?
他们基本上是代码味道。如果你可以消除它们,或者将它们从业务逻辑中推开,那么你就会更好。