public void Init()
 {
     this.testSubject = new OperationCache();
     this.testSubject.Add(this.actionWithBindingParameterWrapper1);
     this.testSubject.Add(this.actionWithBindingParameterWrapper2);
     this.testSubject.Add(this.serviceOperationWrapper);
 }
        /// <summary>
        /// Gets the set of actions bound to any of the given binding parameter types.
        /// </summary>
        /// <param name="bindingParameterTypes">The binding parameter types.</param>
        /// <returns>The operations bound to any of the specified types.</returns>
        private List <OperationWrapper> GetServiceActionsBySpecificBindingParameterTypes(IEnumerable <ResourceType> bindingParameterTypes)
        {
            if (!this.TryLoadActionProvider())
            {
                return(EmptyServiceOperationWrapperList);
            }

            OperationCache existingOperations = new OperationCache();

            // DEVNOTE: We create a list to force enumeration here (rather than waiting for serialization-time enumeration) to preserve call-order.
            return(bindingParameterTypes.SelectMany(resourceType => this.GetServiceActionsBySpecificBindingParameterType(resourceType, existingOperations)).ToList());
        }
        /// <summary>
        /// Validates if a service action is advertisable.
        /// </summary>
        /// <param name="resourceType">Resource type to which the service action is bound to.</param>
        /// <param name="serviceAction">Service action to be validated for advertisement.</param>
        /// <param name="existingOperations">The current set of actions. Used to avoid duplicate actions.</param>
        /// <returns>Validated service operation to be advertised. Null, if the service operation is not suppose to be advertised.</returns>
        private OperationWrapper ValidateCanAdvertiseServiceAction(ResourceType resourceType, ServiceAction serviceAction, OperationCache existingOperations)
        {
            Debug.Assert(resourceType != null && resourceType.ResourceTypeKind == ResourceTypeKind.EntityType, "resourceType != null && resourceType.ResourceTypeKind == ResourceTypeKind.EntityType");

            if (serviceAction == null)
            {
                return(null);
            }

            Debug.Assert(!String.IsNullOrEmpty(serviceAction.Name), "The name of the service operation was null or empty");

            if (existingOperations.Contains(serviceAction))
            {
                throw new DataServiceException(500, Strings.DataServiceActionProviderWrapper_DuplicateAction(serviceAction.Name));
            }

            ServiceActionParameter bindingParameter = (ServiceActionParameter)serviceAction.BindingParameter;

            if (bindingParameter == null)
            {
                Debug.Assert(!String.IsNullOrEmpty(serviceAction.Name), "The name of the service action was null or empty");
                throw new DataServiceException(500, Strings.DataServiceActionProviderWrapper_ServiceActionBindingParameterNull(serviceAction.Name));
            }

            ResourceType bindingParameterType = bindingParameter.ParameterType;

            Debug.Assert(bindingParameterType != null, "bindingParameterType != null");

            // We only support advertising actions for entities and not entity collections. Since resourceType must be an entity type,
            // IsAssignableFrom will fail when the bindingParameterType is an entity collection type.
            if (!bindingParameterType.IsAssignableFrom(resourceType))
            {
                throw new DataServiceException(500, Strings.DataServiceActionProviderWrapper_ResourceTypeMustBeAssignableToBindingParameterResourceType(serviceAction.Name, bindingParameterType.FullName, resourceType.FullName));
            }

            Debug.Assert(bindingParameterType.ResourceTypeKind == ResourceTypeKind.EntityType, "We only support advertising actions for entities and not entity collections.");
            OperationWrapper operationWrapper = this.provider.ValidateOperation(serviceAction);

            if (operationWrapper != null)
            {
                existingOperations.Add(operationWrapper);
            }

            return(operationWrapper);
        }
        /// <summary>
        /// Gets the set of actions bound to the specific parameter type, either from the cache or by calling the provider.
        /// </summary>
        /// <param name="bindingParameterType">The binding parameter type.</param>
        /// <param name="existingOperations">The cache of known actions, used to detect duplicates.</param>
        /// <returns>The operations bound to the specific type.</returns>
        private IEnumerable <OperationWrapper> GetServiceActionsBySpecificBindingParameterType(ResourceType bindingParameterType, OperationCache existingOperations)
        {
            IEnumerable <OperationWrapper> operationWrappersPerType;

            if (!this.ServiceActionByResourceTypeCache.TryGetValue(bindingParameterType, out operationWrappersPerType))
            {
                Debug.Assert(this.actionProvider != null, "this.actionProvider != null");
                IEnumerable <ServiceAction> serviceActions = this.actionProvider.GetServiceActionsByBindingParameterType(this.OperationContext, bindingParameterType);

                if (serviceActions != null && serviceActions.Any())
                {
                    operationWrappersPerType = serviceActions
                                               .Select(serviceAction => this.ValidateCanAdvertiseServiceAction(bindingParameterType, serviceAction, existingOperations))
                                               .Where(serviceOperationWrapper => serviceOperationWrapper != null)
                                               .ToArray();
                }
                else
                {
                    operationWrappersPerType = EmptyServiceOperationWrapperEnumeration;
                }

                // add to the cache
                this.ServiceActionByResourceTypeCache[bindingParameterType] = operationWrappersPerType;
            }

            Debug.Assert(operationWrappersPerType != null, "operationWrappersPerType != null");
            return(operationWrappersPerType);
        }