void Main() { var serviceConfiguration = new ServiceConfiguration( new NetTcpBinding(SecurityMode.None), "localhost", 8900, int.MaxValue, int.MaxValue, true); using (var host = new WcfTestHost<ICustomerService>(new CustomerService(), serviceConfiguration)) { host .CreateProxy() .GetAll().Dump(); } } public class CustomerService : ICustomerService { public IQueryable<Customer> GetAll() { return new List<Customer> { new Customer { Name = "Bill" } }.AsQueryable(); } } [ServiceContract] public interface ICustomerService { [OperationContract] IQueryable<Customer> GetAll(); } public class Customer { public string Name { get; set; } } public class ServiceConfiguration { public ServiceConfiguration(Binding binding, string hostName, int port, long maxReceivedMessageSize, int maxBufferSize, bool prepareForLongOperation) { Binding = binding; HostName = hostName; Port = port; MaxReceivedMessageSize = maxReceivedMessageSize; MaxBufferSize = maxBufferSize; PrepareForLongOperation = prepareForLongOperation; Url = string .Format( "{0}://{1}:{2}//{3}", binding.Scheme, hostName, port, Guid.NewGuid()); } public Binding Binding { get; private set; } public string HostName { get; private set; } public int Port { get; private set; } public long MaxReceivedMessageSize { get; private set; } public int MaxBufferSize { get; private set; } public bool PrepareForLongOperation { get; private set; } public string Url { get; private set; } } public class UnhandledErrorFault { public UnhandledErrorFault(Exception ex, string message, string stackTrace) { if (ex != null) { ExceptionType = ex.GetType().FullName; } Message = message; StackTrace = stackTrace; } public string ExceptionType { get; private set; } public string Message { get; private set; } public string StackTrace { get; private set; } } internal class ErrorHandlerBehavior : IErrorHandler, IServiceBehavior { private Type ServiceType { get; set; } void IServiceBehavior.Validate(ServiceDescription description, ServiceHostBase host) { } void IServiceBehavior.AddBindingParameters( ServiceDescription description, ServiceHostBase host, Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters) { } void IServiceBehavior.ApplyDispatchBehavior( ServiceDescription description, ServiceHostBase host) { ServiceType = description.ServiceType; foreach (ChannelDispatcher dispatcher in host.ChannelDispatchers) { dispatcher.ErrorHandlers.Add(this); } } bool IErrorHandler.HandleError(Exception error) { return false; } void IErrorHandler.ProvideFault(Exception error, MessageVersion version, ref Message fault) { var faultException = error as FaultException; if (faultException == null) { var data = new UnhandledErrorFault(error, error.Message, error.StackTrace); faultException = new FaultException<UnhandledErrorFault>(data); } var messageFault = faultException.CreateMessageFault(); fault = Message.CreateMessage(version, messageFault, faultException.Action); } } public class InstanceProvider : IInstanceProvider { private readonly object serviceInstance; public InstanceProvider(object serviceInstance) { this.serviceInstance = serviceInstance; } public object GetInstance(InstanceContext instanceContext) { return GetInstance(instanceContext, null); } public object GetInstance(InstanceContext instanceContext, Message message) { return serviceInstance; } public void ReleaseInstance(InstanceContext instanceContext, object instance) { } } public class DependencyServiceBehavior : IServiceBehavior { private readonly object serviceInstance; public DependencyServiceBehavior(object serviceInstance) { this.serviceInstance = serviceInstance; } public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { foreach (var endpoint in serviceHostBase.ChannelDispatchers.OfType<ChannelDispatcher>().SelectMany(cd => cd.Endpoints)) { endpoint.DispatchRuntime.InstanceProvider = new InstanceProvider(serviceInstance); } } public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { } } public class WcfServiceFactory<TServiceContract> { private TimeSpan timeSpan = new TimeSpan(0, 0, 20); public ICommunicationObject Create(TServiceContract service, ServiceConfiguration serviceConfiguration) { if (serviceConfiguration.PrepareForLongOperation) { timeSpan = new TimeSpan(0, 0, 50, 0); var readerQuotas = new XmlDictionaryReaderQuotas { MaxArrayLength = 100 * 1024 ////Set max array size to 100kb ////MaxStringContentLength = _sanebutusablelimit_, ////MaxBytesPerRead = _sanebutusablelimit_, ////MaxDepth = _sanebutusablelimit_, ////MaxNameTableCharCount = _sanebutusablelimit_ }; serviceConfiguration .Binding .GetType() .GetProperty("ReaderQuotas") .SetValue(serviceConfiguration.Binding, readerQuotas, null); var dynamicBinding = (dynamic)serviceConfiguration.Binding; dynamicBinding.MaxBufferPoolSize = int.MaxValue; dynamicBinding.MaxBufferSize = serviceConfiguration.MaxBufferSize; dynamicBinding.MaxReceivedMessageSize = serviceConfiguration.MaxReceivedMessageSize; } serviceConfiguration.Binding.OpenTimeout = timeSpan; serviceConfiguration.Binding.CloseTimeout = timeSpan; serviceConfiguration.Binding.SendTimeout = timeSpan; serviceConfiguration.Binding.ReceiveTimeout = timeSpan; var host = new ServiceHost(service.GetType()) { CloseTimeout = timeSpan, OpenTimeout = timeSpan }; var serviceContractType = typeof(TServiceContract); host.AddServiceEndpoint(serviceContractType, serviceConfiguration.Binding, serviceConfiguration.Url); var serviceDebugBehavior = (ServiceDebugBehavior)host.Description.Behaviors[typeof(ServiceDebugBehavior)]; if (host.Description.Behaviors.Find<ErrorHandlerBehavior>() == null) { host.Description.Behaviors.Add(new ErrorHandlerBehavior()); } host.Description.Behaviors.Add(new DependencyServiceBehavior(service)); serviceDebugBehavior.IncludeExceptionDetailInFaults = true; try { host.Open(); } catch (TimeoutException timeoutException) { Debug.WriteLine("Failed to close the service host - Exception: " + timeoutException.Message); throw; } catch (CommunicationException communicationException) { if (communicationException.Message.Contains("10013")) { PortAlreadyUsed(serviceConfiguration, communicationException); } Debug.WriteLine("Failed to close the service host - Exception: " + communicationException.Message); throw; } return host; } private void PortAlreadyUsed(ServiceConfiguration serviceConfiguration, CommunicationException communicationException) { var message = string.Format("The port {0} used for the test could be in use by another application.", serviceConfiguration.Port); throw new CommunicationException(message, communicationException); } } public class WcfTestHost<TServiceContract> : IDisposable { private readonly ServiceConfiguration serviceConfiguration; private readonly TServiceContract serviceInstance; private ICommunicationObject host; private ChannelFactory<TServiceContract> factory; private TServiceContract proxy; public WcfTestHost(TServiceContract serviceInstance, ServiceConfiguration serviceConfiguration) { this.serviceConfiguration = serviceConfiguration; this.serviceInstance = serviceInstance; } public TServiceContract CreateProxy() { host = new WcfServiceFactory<TServiceContract>() .Create(serviceInstance, serviceConfiguration); factory = new ChannelFactory<TServiceContract>(serviceConfiguration.Binding); proxy = factory.CreateChannel(new EndpointAddress(serviceConfiguration.Url)); return proxy; } public void Dispose() { if (factory != null) { if (factory.State == CommunicationState.Opened) { factory.Close(); } factory = null; } TearDown(); } private void TearDown() { if (host == null) { return; } try { if (host.State == CommunicationState.Opened || host.State == CommunicationState.Opening) { host.Close(new TimeSpan(0, 0, 0, 1)); } } catch (TimeoutException timeoutEx) { Debug.WriteLine("Failed to close the service host - Exception: " + timeoutEx.Message); } catch (CommunicationException communicationEx) { Debug.WriteLine("Failed to close the service host - Exception: " + communicationEx.Message); } catch (Exception ex) { Debug.WriteLine("Exception: " + ex.Message); throw; } finally { host = null; } } }