/// <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);
                }
            }
        }
Example #2
0
        /// <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;
                }
            }
        }