/// <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; }