public static string AddServiceHostBasicHttp(Type serviceType, Type contractType = null, string serviceId = null, MessageSize messageSize = MessageSize.Undefined, bool exposeWsdl = false, string baseAddress = null, string basePath = null, string extension = null, bool useHttps = false) { // Before we do anything else, we start looking for optional parameters and setting appropriate defaults if (contractType == null) contractType = GetContractTypeFromServiceType(serviceType); if (baseAddress == null) { baseAddress = BaseUrl; if (string.IsNullOrEmpty(baseAddress)) throw new Core.Exceptions.NullReferenceException("Static BaseUrl property must be set on the ServiceGarden class before the garden can be populated."); } if (basePath == null) { basePath = BasePath; if (!string.IsNullOrEmpty(basePath) && !basePath.EndsWith("/")) basePath += "/"; } if (extension == null) { extension = GetSetting("ServiceBasicHTTPExtension", contractType.Name, "basic"); if (!string.IsNullOrEmpty(extension) && !extension.StartsWith("/")) extension = "/" + extension; } if (serviceId == null) serviceId = contractType.Name; if (messageSize == MessageSize.Undefined) messageSize = GetMessageSize(contractType.Name); // Starting our regular method if (!string.IsNullOrEmpty(basePath) && !basePath.EndsWith("/")) basePath += "/"; if (!string.IsNullOrEmpty(extension) && !extension.StartsWith("/")) extension = "/" + extension; var protocol = useHttps ? "https://" : "http://"; var serviceFullAddress = protocol + baseAddress + "/" + basePath + serviceId + extension; var serviceNamespace = GetServiceNamespace(serviceType, contractType); var addresses = new[] { new Uri(serviceFullAddress) }; var host = CreateServiceHost(serviceType, contractType, addresses); // Binding needed var securityMode = useHttps ? BasicHttpSecurityMode.Transport : BasicHttpSecurityMode.None; var binding = new BasicHttpBinding(securityMode) {SendTimeout = new TimeSpan(0, 10, 0)}; if (!string.IsNullOrEmpty(serviceNamespace)) binding.Namespace = serviceNamespace; ServiceHelper.ConfigureMessageSizeOnBasicHttpBinding(messageSize, binding); // Endpoint configuration if (BeforeEndpointAdded != null) { var endpointAddedArgs = new EndpointAddedEventArgs { Binding = binding, ContractType = contractType, ServiceFullAddress = serviceFullAddress }; BeforeEndpointAdded(null, endpointAddedArgs); serviceFullAddress = endpointAddedArgs.ServiceFullAddress; } var endpoint = host.AddServiceEndpoint(contractType, binding, serviceFullAddress); if (!string.IsNullOrEmpty(serviceNamespace) && endpoint.Contract != null && endpoint.Contract.Namespace != serviceNamespace) endpoint.Contract.Namespace = serviceNamespace; if (HttpCrossDomainCallsAllowed) endpoint.Behaviors.Add(new CrossDomainScriptBehavior()); // Maybe we expose a WSDL endpoint too if (exposeWsdl) { var wsdlFullPath = serviceFullAddress + "/wsdl"; var smb = new ServiceMetadataBehavior { HttpGetEnabled = true, HttpGetUrl = new Uri(wsdlFullPath) }; host.Description.Behaviors.Add(smb); var mexBinding = MetadataExchangeBindings.CreateMexHttpBinding(); host.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, wsdlFullPath); } var serviceKey = serviceFullAddress; if (Hosts.ContainsKey(serviceKey)) { if (Hosts[serviceKey].Host.State == CommunicationState.Opened) { try { Hosts[serviceKey].Host.Close(); } catch { } // Nothing we can do } Hosts.Remove(serviceKey); } // If needed, we fire the static event, so people can tie into this to programmatically manipulate the host or binding if need be if (BeforeHostAdded != null) BeforeHostAdded(null, new HostAddedEventArgs { Host = host, ServiceFullAddress = serviceFullAddress, Binding = binding, ContractType = contractType, MessageSize = messageSize, ServiceId = serviceId, ServiceType = serviceType }); lock (Hosts) Hosts.Add(serviceKey, new HostWrapper(host, serviceFullAddress)); return StartService(serviceKey); }
public static string AddServiceHostNetTcp(Type serviceType, Type contractType = null, string serviceId = null, MessageSize messageSize = MessageSize.Undefined, int port = -1) { // Before we do anything else, we start looking for optional parameters and setting appropriate defaults if (contractType == null) contractType = GetContractTypeFromServiceType(serviceType); if (serviceId == null) serviceId = contractType.Name; if (messageSize == MessageSize.Undefined) messageSize = GetMessageSize(contractType.Name); // Starting our regular method var baseAddress = BaseUrl; if (string.IsNullOrEmpty(baseAddress)) throw new Core.Exceptions.NullReferenceException("Static BaseUrl property must be set on the ServiceGarden class before the garden can be populated."); if (BasePort == -1) throw new Core.Exceptions.NullReferenceException("Static BasePort property must be set on the ServiceGarden class before the garden can be populated."); if (port == -1) { port = BasePort; port += _portOffset; _portOffset++; } var path = BasePath; if (!string.IsNullOrEmpty(path) && !path.EndsWith("/")) path += "/"; var serviceFullAddress = "net.tcp://" + baseAddress + ":" + port + "/" + path + serviceId; var serviceNamespace = GetServiceNamespace(serviceType, contractType); var addresses = new[] { new Uri(serviceFullAddress) }; var host = CreateServiceHost(serviceType, contractType, addresses); // Binding needed var binding = new NetTcpBinding(SecurityMode.None) { SendTimeout = new TimeSpan(0, 10, 0) }; if (!string.IsNullOrEmpty(serviceNamespace)) binding.Namespace = serviceNamespace; ServiceHelper.ConfigureMessageSizeOnNetTcpBinding(messageSize, binding); // Endpoint configuration if (BeforeEndpointAdded != null) { var endpointAddedArgs = new EndpointAddedEventArgs {Binding = binding, ContractType = contractType, ServiceFullAddress = serviceFullAddress}; BeforeEndpointAdded(null, endpointAddedArgs); serviceFullAddress = endpointAddedArgs.ServiceFullAddress; } var endpoint = host.AddServiceEndpoint(contractType, binding, serviceFullAddress); if (!string.IsNullOrEmpty(serviceNamespace) && endpoint.Contract != null && endpoint.Contract.Namespace != serviceNamespace) endpoint.Contract.Namespace = serviceNamespace; var serviceKey = serviceFullAddress; if (Hosts.ContainsKey(serviceKey)) { if (Hosts[serviceKey].Host.State == CommunicationState.Opened) { try { Hosts[serviceKey].Host.Close(); } catch { } // Nothing we can do } Hosts.Remove(serviceKey); } // We check whether the service we host has a custom service behavior attribute. If not, we make it a per-call service var customAttributes = serviceType.GetCustomAttributes(typeof(ServiceBehaviorAttribute), true); if (customAttributes.Length == 0) // No explicitly set behavior attribute found { var serviceBehaviorFound = false; foreach (var behavior in host.Description.Behaviors) { var serviceBehavior = behavior as ServiceBehaviorAttribute; if (serviceBehavior != null) { serviceBehavior.InstanceContextMode = InstanceContextMode.PerCall; serviceBehaviorFound = true; break; } } if (!serviceBehaviorFound) host.Description.Behaviors.Add(new ServiceBehaviorAttribute { InstanceContextMode = InstanceContextMode.PerCall }); } // If needed, we fire the static event, so people can tie into this to programmatically manipulate the host or binding if need be); if (BeforeHostAdded != null) BeforeHostAdded(null, new HostAddedEventArgs { Host = host, ServiceFullAddress = serviceFullAddress, Binding = binding, ContractType = contractType, MessageSize = messageSize, ServiceId = serviceId, ServiceType = serviceType }); lock (Hosts) Hosts.Add(serviceKey, new HostWrapper(host, serviceFullAddress)); return StartService(serviceKey); }