public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers) { foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints) { DispatchRuntime runtime = endpointDispatcher.DispatchRuntime; ServiceHost serviceHost = (ServiceHost)serviceHostBase; if (null != serviceHost.SingletonInstance) { runtime.SingletonInstanceContext = new InstanceContext(serviceHostBase, serviceHost.SingletonInstance); SetDisposableInstance(serviceHost, serviceHost.SingletonInstance); } else { object serviceInstance = Activator.CreateInstance(serviceDescription.ServiceType); runtime.SingletonInstanceContext = new InstanceContext(serviceInstance); SetDisposableInstance(serviceHost, serviceInstance); } IInstanceContextProvider provider = new SingletonInstanceContextProvider(runtime); runtime.InstanceContextProvider = provider; } } }
void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { var q = from channelDispatcher in ChannelDispatchers.OfType <ChannelDispatcher>() from endpointDispatcher in channelDispatcher.Endpoints where !endpointDispatcher.IsSystemEndpoint join endpoint in serviceDescription.Endpoints on Tuple.Create(endpointDispatcher.EndpointAddress, endpointDispatcher.ContractName, endpointDispatcher.ContractNamespace) equals Tuple.Create(endpoint.Address, endpoint.Contract.Name, endpoint.Contract.Namespace) group new { endpointDispatcher, endpoint } by endpoint.Contract into contract group contract by scope.ComponentRegistry.RegistrationsFor(new TypedService(contract.Key.ContractType)).Single(); foreach (var registration in q) { ServiceBehaviorAttribute behavior; object behaviorObj; if (registration.Key.Metadata.TryGetValue("behavior", out behaviorObj)) { behavior = (ServiceBehaviorAttribute)behaviorObj; } else { behavior = registration.Key.Activator.LimitType.GetCustomAttribute <ServiceBehaviorAttribute>(); } if (behavior == null) { behavior = new ServiceBehaviorAttribute(); } IInstanceContextProvider provider; switch (behavior.InstanceContextMode) { case InstanceContextMode.Single: provider = new SingletonInstanceContextProvider(this, scope, registration.Key); break; case InstanceContextMode.PerSession: provider = new PerSessionInstanceContextProvider(this, scope); break; case InstanceContextMode.PerCall: provider = new PerCallInstanceContextProvider(this, scope); break; default: throw new InvalidOperationException(); } foreach (var contract in registration) { foreach (var b in contract.Key.Operations.SelectMany(op => op.OperationBehaviors).OfType <DataContractSerializerOperationBehavior>()) { b.IgnoreExtensionDataObject = behavior.IgnoreExtensionDataObject; b.MaxItemsInObjectGraph = behavior.MaxItemsInObjectGraph; } foreach (var x in contract) { var runtime = x.endpointDispatcher.DispatchRuntime; runtime.ConcurrencyMode = behavior.ConcurrencyMode; runtime.EnsureOrderedDispatch = behavior.EnsureOrderedDispatch; runtime.ValidateMustUnderstand = behavior.ValidateMustUnderstand; runtime.AutomaticInputSessionShutdown = behavior.AutomaticSessionShutdown; runtime.TransactionAutoCompleteOnSessionClose = behavior.TransactionAutoCompleteOnSessionClose; runtime.ReleaseServiceInstanceOnTransactionComplete = behavior.ReleaseServiceInstanceOnTransactionComplete; if (!behavior.UseSynchronizationContext) { runtime.SynchronizationContext = null; } var address = x.endpointDispatcher.EndpointAddress; switch (behavior.AddressFilterMode) { case AddressFilterMode.Any: x.endpointDispatcher.AddressFilter = new MatchAllMessageFilter(); break; case AddressFilterMode.Prefix: x.endpointDispatcher.AddressFilter = new PrefixEndpointAddressMessageFilter(x.endpointDispatcher.EndpointAddress); break; case AddressFilterMode.Exact: x.endpointDispatcher.AddressFilter = new EndpointAddressMessageFilter(x.endpointDispatcher.EndpointAddress); break; } Console.WriteLine("Channel: {0}, Endpoint: {1}, Contract: {2}, Callback: {3}, Registration: {4}", x.endpointDispatcher.ChannelDispatcher.BindingName, x.endpointDispatcher.EndpointAddress, contract.Key.ConfigurationName, contract.Key.CallbackContractType?.Name, registration.Key.Activator.LimitType.Name ); runtime.InstanceProvider = new InstanceProvider(contract.Key.CallbackContractType, registration.Key); runtime.InstanceContextProvider = provider; } } } }