Proxies
IRPの第一の側面は、アーティファクトへのプロキシを使用することで、意図の構成を可能にする能力にあります。これらのプロキシは、識別子の保持者(サービスサイドのバインディングステップを可能にする)であり、意図を表す式の構築者であると考えることができます。具体的には、例えば、IRPコンテキストのGet*メソッドに反映されます。
The first aspect of IRP is in its ability to enable composition of intent by using proxies to artifacts. One can view these proxies are holders of identifiers (enabling service-side binding steps) and builders for expressions that represent the intent. Concretely, this gets reflected in the Get* methods on an IRP context, for example:
code:C#
IAsyncReactiveQbservable<T> GetObservable<T>(Uri observableId);
IAsyncReactiveQbserver<T> GetObserver<T>(Uri observerId);
IAsyncReactiveQubscription GetSubscription(Uri subscriptionId);
プロキシのExpressionプロパティにアクセスすると、Get*メソッドに渡されたアーティファクトの識別子をNameに持つParameterExpressionが表示されます。
When accessing the Expression property on a proxy, one will find a ParameterExpression whose Name refers to the identifier of the artifact that was passed to the Get* method.
問い合わせ演算子を適用すると、演算子のオペランドの式を構成するより大きな式木が作成されます。この式木は、その後、さらなる構成に使用できるオブジェクトにカプセル化されます。
Applying query operators results in the creation of bigger expression trees that compose the expressions of the operator’s operands, which subsequently get encapsulated in an object that can be used for further composition:
code:C#
var numbers = ctx.GetObservable<int>(new Uri("eg://numbers"));
// numbers.Expression
// ~ Expression.Parameter("eg://numbers")
var positive = numbers.Where(x => x >= 0);
// positive.Expression
// ~ Expression.Call(
// Where,
// Expression.Parameter("eg://numbers"),
// Expression.Lambda(...)
// )
var negative = positive.Select(x => -x);
// negative.Expression
// ~ Expression.Call(
// Select,
// Expression.Call(
// Where,
// Expression.Parameter("eg://numbers"),
// Expression.Lambda(...)
// ),
// Expression.Lambda(...)
// )
ここで重要なのは、アーティファクトの合成は完全にインメモリーで行われ、サービスと通信することはないということです。インテントを合成した後は、ホットアーティファクト(サブスクリプションやストリームなど)の作成やコールドアーティファクト(パラメータ化されたオブザーバやオブザーバなど)の定義などのDDL操作を行うために使用できます。例えば
It’s important to realize that composition of artifacts happens entirely in-memory and never communicates with a service. After composing the intent, it can be used to perform a DDL operation such as the creation of a hot artifact (e.g. a subscription or stream) or the definition of a cold artifact (e.g. a parameterized observable or observer). For example:
code:C#
await negative.SubscribeAsync(new Uri("eg://sub/neg"), ...);