Example #1
0
        /// <summary>
        /// Creates endpoints based on the specified description.
        /// </summary>
        /// <param name="description">The <see cref="DomainServiceDescription"/> of the <see cref="DomainService"/> to create the endpoints for.</param>
        /// <param name="serviceHost">The service host for which the endpoints will be created.</param>
        /// <returns>The endpoints that were created.</returns>
        public override IEnumerable <ServiceEndpoint> CreateEndpoints(DomainServiceDescription description, DomainServiceHost serviceHost)
        {
            Debug.Assert(this.Name != null, "Name has not been set.");
            Debug.Assert(this.domainDataServiceMetadata == null, "this.domainDataServiceMetadata == null");

            if (description.Attributes[typeof(EnableClientAccessAttribute)] != null)
            {
                // The metadata object will tell us which operations we should expose for the OData end point.
                this.domainDataServiceMetadata = new OData.DomainDataServiceMetadata(description);

                // The OData endpoint doesn't expose all operations in the DomainService, but only operations with parameter and return types
                // which are supported by the data service.  WCF doesn't allow us to create a contract without any operation.
                if (this.domainDataServiceMetadata.Sets.Count > 0 || this.domainDataServiceMetadata.ServiceOperations.Count > 0)
                {
                    // Infer the contract from Domain service description.
                    ContractDescription contract = this.CreateContract(description);

                    // Make endpoints that expose the inferred contract on the given base addresses.
                    foreach (Uri address in serviceHost.BaseAddresses)
                    {
                        yield return(this.CreateEndpointForAddress(description, contract, address));
                    }
                }
            }
        }
        /// <summary>
        /// Creates endpoints based on the specified description.
        /// </summary>
        /// <param name="description">The <see cref="DomainServiceDescription"/> of the <see cref="DomainService"/> to create the endpoints for.</param>
        /// <param name="serviceHost">The service host for which the endpoints will be created.</param>
        /// <returns>The endpoints that were created.</returns>
        public override IEnumerable<ServiceEndpoint> CreateEndpoints(DomainServiceDescription description, DomainServiceHost serviceHost)
        {
            Debug.Assert(this.Name != null, "Name has not been set.");
            Debug.Assert(this.domainDataServiceMetadata == null, "this.domainDataServiceMetadata == null");

            if (description.Attributes[typeof(EnableClientAccessAttribute)] != null)
            {
                // The metadata object will tell us which operations we should expose for the OData end point.
                this.domainDataServiceMetadata = new OData.DomainDataServiceMetadata(description);

                // The OData endpoint doesn't expose all operations in the DomainService, but only operations with parameter and return types
                // which are supported by the data service.  WCF doesn't allow us to create a contract without any operation.
                if (this.domainDataServiceMetadata.Sets.Count > 0 || this.domainDataServiceMetadata.ServiceOperations.Count > 0)
                {
                    // Infer the contract from Domain service description.
                    ContractDescription contract = this.CreateContract(description);

                    // Make endpoints that expose the inferred contract on the given base addresses.
                    foreach (Uri address in serviceHost.BaseAddresses)
                    {
                        yield return this.CreateEndpointForAddress(description, contract, address);
                    }
                }
            }
        }
        /// <summary>Constructs the operation selector for runtime.</summary>
        /// <param name="endpoint">End point.</param>
        /// <param name="metadata">Domain data service metadata.</param>
        public DomainDataServiceOperationSelector(
            ServiceEndpoint endpoint,
            DomainDataServiceMetadata metadata)
            : base(DomainDataServiceOperationSelector.ExtractNonRootQueryServiceOperations(endpoint, metadata))
        {
            this.baseUri = endpoint.ListenUri;
            this.serviceRootQueryOperations = new Dictionary<string, string>();

            // Collect all the query operations, since they are to be handled by selector in this class.
            foreach (var od in endpoint.Contract.Operations)
            {
                string resourceSetName = DomainDataServiceOperationSelector.GetRootQueryOperation(od, metadata);
                if (!String.IsNullOrEmpty(resourceSetName))
                {
                    Debug.Assert(!this.serviceRootQueryOperations.ContainsKey(resourceSetName), "There should only be 1 default query operation per set.");

                    // Note the fact that requests on resourceSet correspond to the given operation.
                    this.serviceRootQueryOperations.Add(resourceSetName, od.Name);
                }
            }
        }
 /// <summary>Constructs factory for creating data services using the given domain service description.</summary>
 /// <param name="metadata">Data Service metadata object corresponding to domain service description.</param>
 internal DomainDataServiceFactory(DomainDataServiceMetadata metadata)
 {
     this.domainDataServiceMetadata = metadata;
 }
        /// <summary>
        /// Given an operation descriptions, detects if it corresponds to a root query operation.
        /// </summary>
        /// <param name="od">Given operation description.</param>
        /// <param name="metadata">Metadata for the domain data service.</param>
        /// <returns>null if operation does not correspond to root query operation, otherwise the name of the resource set.</returns>
        private static string GetRootQueryOperation(OperationDescription od, DomainDataServiceMetadata metadata)
        {
            ResourceSet resourceSet;

            if (metadata.Sets.TryGetValue(od.Name, out resourceSet))
            {
                Debug.Assert(resourceSet != null, "resourceSet != null");
                return resourceSet.Name;
            }

            return null;
        }
        /// <summary>
        /// Obtains the service operations available on the model and hands over all those
        /// operations to the base class for processing. The root query operations are
        /// handled by this class itself.
        /// </summary>
        /// <param name="endpoint">Endpoint on which operations are defined.</param>
        /// <param name="metadata">Metadata of the domain service.</param>
        /// <returns>Endpoint that contains all the operations that base class needs to process.</returns>
        private static ServiceEndpoint ExtractNonRootQueryServiceOperations(ServiceEndpoint endpoint, DomainDataServiceMetadata metadata)
        {
            ContractDescription cd = new ContractDescription(endpoint.Contract.Name);

            // Provide all the non-root query operations to the base class, only provide those operations that
            // have some representation on the domain data service.
            foreach (OperationDescription od in endpoint.Contract.Operations)
            {
                if (metadata.ServiceOperations.Keys.Contains(od.Name))
                {
                    Debug.Assert(
                        String.IsNullOrEmpty(DomainDataServiceOperationSelector.GetRootQueryOperation(od, metadata)),
                        "Service operation must not be a root query operation.");
                    cd.Operations.Add(od);
                }
            }

            return new ServiceEndpoint(cd, endpoint.Binding, endpoint.Address)
            {
                ListenUri = endpoint.ListenUri
            };
        }
 /// <summary>Constructs the data service provider object.</summary>
 /// <param name="domainServiceDataServiceMetadata">Metadata information for the current instance.</param>
 /// <param name="result">Root queryable for current request.</param>
 internal DomainDataServiceProvider(DomainDataServiceMetadata domainServiceDataServiceMetadata, object result)
 {
     this.metadata = domainServiceDataServiceMetadata;
     this.CurrentDataSource = new object();
     this.Result = result;
 }