/// <summary> /// Adjusts the contract and behavior of each operation that returns <see cref="System.IObservable{T}"/>. /// </summary> /// <param name="contractDescription">The contract description to be modified.</param> /// <param name="endpoint">The endpoint that exposes the contract.</param> /// <param name="dispatchRuntime">The dispatch runtime that controls service execution.</param> public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime) { Contract.Assume(contractDescription != null); foreach (var operation in contractDescription.Operations) { Contract.Assume(operation != null); if (ObservableMethodInvoker.IsObservableMethod(operation.SyncMethod)) { InitializeObservableOperation(operation, ReturnAsListDefault); } } }
/// <summary> /// Ensures that the method to which this attribute is applied is synchronous and returns <see cref="System.IObservable{T}"/>. /// </summary> /// <param name="operationDescription">The operation being examined. Use for examination only. If the operation /// description is modified, the results are undefined.</param> public void Validate(OperationDescription operationDescription) { Contract.Assume(operationDescription != null); if (operationDescription.SyncMethod == null) { throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Errors.OperationIsNotSynchronous, operationDescription.Name)); } if (!ObservableMethodInvoker.IsObservableMethod(operationDescription.SyncMethod)) { throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Errors.OperationIsNotObservable, operationDescription.Name)); } }
private static void InitializeObservableOperation(OperationDescription operation, bool returnAsListDefault) { Contract.Requires(operation != null); Contract.Requires(operation.SyncMethod != null); var hasObservableOperationBehavior = false; var returnAsList = false; foreach (var behavior in operation.Behaviors) { var observableOperationAttribute = behavior as ObservableOperationAttribute; if (observableOperationAttribute != null) { returnAsList = observableOperationAttribute.ReturnAsList; hasObservableOperationBehavior = true; } } if (!hasObservableOperationBehavior) { operation.Behaviors.Add( new ObservableOperationAttribute() { ReturnAsList = returnAsList = returnAsListDefault }); } Contract.Assume(operation.SyncMethod != null); var dataType = ObservableMethodInvoker.GetObservableDataType(operation.SyncMethod.ReturnType); var returnType = returnAsList ? Rxx.GeneralReflection.MakeGenericType(typeof(IList <>), dataType) : dataType; foreach (var message in operation.Messages) { Contract.Assume(message != null); if (message.Direction == MessageDirection.Output) { Contract.Assume(message.Body.ReturnValue != null); message.Body.ReturnValue.Type = returnType; } } }