私はReactiveExtensionsで多くの実験を行っており、現在、サブスクライバーに通知を送信しながら、プロシージャをキューに入れて任意の方法で実行できるシステムを作成しようとしています。
現在、データベースアクセスをUserAccessクラス内にカプセル化して、ユーザーを追加するメソッドを公開しています。その方法では、データベースにユーザーを追加するアクションをキューに入れたいと思います。そこで、メソッドQueueJob(Action)を公開するTクラスのJobProcessorを作成し、ユーザーにこのクラスを実装させました。私の問題は、アクションがUserパラメーターを受け取るため、ObservableのOnNextメソッド内からアクションを呼び出す方法がわからないことです。
迎え角が間違っていて、デザインの把握に問題があるはずです。たとえば、ユーザーをQueueJobプロシージャに渡す必要があることはわかっていますが、クリーンな方法でそれを行う方法がわかりません。
public class UserAccess : JobProcessor<User>
{
public void AddUser(User user)
{
QueueJob(usr =>
{
using (var db = new CenterPlaceModelContainer())
{
db.Users.Add(usr);
}
});
[...]
public abstract class JobProcessor<T>
{
// Either Subject<T> or Subject<Action<T>>
private Subject<Action<T>> JobSubject = new Subject<Action<T>>();
public JobProcessor()
{
JobSubject
/* Insert Rx Operators Here */
.Subscribe(OnJobNext, OnJobError, OnJobComplete);
}
private void OnJobNext(Action<T> action)
{
// ???
}
private void OnJobError(Exception exception)
{
}
private void OnJobComplete()
{
}
public void QueueJob(Action<T> action)
{
JobSubject.OnNext(action);
}
}
編集1:
QueueJobの署名をに変更しようとしました
QueueJob(T entity, Action<T> action)
今、私はできる
QueueJob(user, usr => { ... } );
しかし、それはあまり直感的ではないようです。エンティティとアクションの両方を渡すフレームワークはあまり見たことがありません。そうすれば、JobProcessorは必要ないかもしれません。
編集2: JobProcessorのサブジェクトタイプをSubjectに変更し、Tを完全に削除しました。外部から参照できるので、手順にユーザーを含める必要がなかったので。現在の唯一の問題は、QueueJobのアクションに渡すユーザーが、アクションの実行の実際の時間の間に変更された場合、ユーザーが変更された情報を持っていることです。望ましくありませんが、私は解決策を探し続けると思います。
私のコードは今です(サンプルにバッファを使用):
public abstract class JobProcessor
{
public Subject<Action> JobSubject = new Subject<Action>();
public JobProcessor()
{
JobSubject
.Buffer(3)
.Subscribe(OnJobNext, OnJobError, OnJobComplete);
}
private void OnJobNext(IList<Action> actionsList)
{
foreach (var element in actionsList)
{
element();
}
}
private void OnJobError(Exception exception)
{
}
private void OnJobComplete()
{
}
public void QueueJob(Action action)
{
JobSubject.OnNext(action);
}
}