/// <summary> /// Creates a contract description for the domain data service endpoint based on the domain service description. /// </summary> /// <param name="description">Domain data service description.</param> /// <returns>Contract description for the domain data service endpoint.</returns> private ContractDescription CreateContract(DomainServiceDescription description) { Type domainServiceType = description.DomainServiceType; ServiceDescription serviceDesc = ServiceDescription.GetService(domainServiceType); // Use names from [ServiceContract], if specified. ServiceContractAttribute sca = TypeDescriptor.GetAttributes(domainServiceType)[typeof(ServiceContractAttribute)] as ServiceContractAttribute; if (sca != null) { if (!String.IsNullOrEmpty(sca.Name)) { serviceDesc.Name = sca.Name; } if (!String.IsNullOrEmpty(sca.Namespace)) { serviceDesc.Name = sca.Namespace; } } ContractDescription contractDesc = new ContractDescription(serviceDesc.Name + this.Name, serviceDesc.Namespace) { ConfigurationName = serviceDesc.ConfigurationName + this.Name, ContractType = domainServiceType }; // Disable metadata generation for the domain data service contract. contractDesc.Behaviors.Add(new ServiceMetadataContractBehavior(true)); // Add domain service behavior which takes care of instantiating DomainServices. ServiceUtils.EnsureBehavior <DomainDataServiceContractBehavior>(contractDesc); // Load the ContractDescription from the DomainServiceDescription. this.LoadContractDescription(contractDesc, description); return(contractDesc); }
/// <summary> /// Create operation corresponding to given DomainService operation. /// </summary> /// <param name="declaringContract">Contract to which operation will belong.</param> /// <param name="operation">DomainService operation.</param> /// <returns>Created operation.</returns> private static OperationDescription CreateOperationDescription(ContractDescription declaringContract, DomainOperationEntry operation) { OperationDescription operationDesc = new OperationDescription(operation.Name, declaringContract); // Propagate behaviors. foreach (IOperationBehavior behavior in operation.Attributes.OfType <IOperationBehavior>()) { operationDesc.Behaviors.Add(behavior); } // Add standard web behaviors. if ((operation.Operation == DomainOperation.Query && ((QueryAttribute)operation.OperationAttribute).HasSideEffects) || (operation.Operation == DomainOperation.Invoke && ((InvokeAttribute)operation.OperationAttribute).HasSideEffects)) { // For operations with side-effects i.e. with WebInvoke attribute, we need to build a default GET like // URI template so that, the parameter processing is taken care of by the WebHttpBehavior selector. WebInvokeAttribute attrib = ServiceUtils.EnsureBehavior <WebInvokeAttribute>(operationDesc); if (attrib.UriTemplate == null) { attrib.UriTemplate = ODataEndpointFactory.BuildDefaultUriTemplate(operation); } } else { ServiceUtils.EnsureBehavior <WebGetAttribute>(operationDesc); } string action = ServiceUtils.GetRequestMessageAction(declaringContract, operationDesc.Name, null); // Define operation input. MessageDescription inputMessageDesc = new MessageDescription(action, MessageDirection.Input); inputMessageDesc.Body.WrapperName = operationDesc.Name; inputMessageDesc.Body.WrapperNamespace = ServiceUtils.DefaultNamespace; for (int i = 0; i < operation.Parameters.Count; i++) { DomainOperationParameter parameter = operation.Parameters[i]; MessagePartDescription parameterPartDesc = new MessagePartDescription(parameter.Name, ServiceUtils.DefaultNamespace) { Index = i, Type = TypeUtils.GetClientType(parameter.ParameterType) }; inputMessageDesc.Body.Parts.Add(parameterPartDesc); } operationDesc.Messages.Add(inputMessageDesc); // Define operation output. string responseAction = ServiceUtils.GetResponseMessageAction(declaringContract, operationDesc.Name, null); MessageDescription outputMessageDesc = new MessageDescription(responseAction, MessageDirection.Output); outputMessageDesc.Body.WrapperName = operationDesc.Name + "Response"; outputMessageDesc.Body.WrapperNamespace = ServiceUtils.DefaultNamespace; if (operation.ReturnType != typeof(void)) { outputMessageDesc.Body.ReturnValue = new MessagePartDescription(operationDesc.Name + "Result", ServiceUtils.DefaultNamespace) { Type = TypeUtils.GetClientType(operation.ReturnType) }; } operationDesc.Messages.Add(outputMessageDesc); return(operationDesc); }