protected virtual void InitializeRuntime() { //First validate the description, which should call all behaviors //'Validate' method. ValidateDescription(); //Build all ChannelDispatchers, one dispatcher per user configured EndPoint. //We must keep thet ServiceEndpoints as a seperate collection, since the user //can change the collection in the description during the behaviors events. ServiceEndpoint[] endPoints = new ServiceEndpoint[Description.Endpoints.Count]; Description.Endpoints.CopyTo(endPoints, 0); var builder = new DispatcherBuilder(this); foreach (ServiceEndpoint se in endPoints) { var commonParams = new BindingParameterCollection(); foreach (IServiceBehavior b in Description.Behaviors) { b.AddBindingParameters(Description, this, Description.Endpoints, commonParams); } var channel = builder.BuildChannelDispatcher(Description.ServiceType, se, commonParams); if (!ChannelDispatchers.Contains(channel)) { ChannelDispatchers.Add(channel); } } //After the ChannelDispatchers are created, and attached to the service host //Apply dispatching behaviors. // // This behavior application order is tricky: first only // ServiceDebugBehavior and ServiceMetadataBehavior are // applied, and then other service behaviors are applied. // It is because those two behaviors adds ChannelDispatchers // and any other service behaviors must be applied to // those newly populated dispatchers. foreach (IServiceBehavior b in Description.Behaviors) { if (b is ServiceMetadataBehavior || b is ServiceDebugBehavior) { b.ApplyDispatchBehavior(Description, this); } } foreach (IServiceBehavior b in Description.Behaviors) { if (!(b is ServiceMetadataBehavior || b is ServiceDebugBehavior)) { b.ApplyDispatchBehavior(Description, this); } } builder.ApplyDispatchBehaviors(); }
protected virtual void InitializeRuntime() { //First validate the description, which should call all behaviors //'Validate' method. ValidateDescription(); //Build all ChannelDispatchers, one dispatcher per user configured EndPoint. //We must keep thet ServiceEndpoints as a seperate collection, since the user //can change the collection in the description during the behaviors events. Dictionary <ServiceEndpoint, ChannelDispatcher> endPointToDispatcher = new Dictionary <ServiceEndpoint, ChannelDispatcher>(); ServiceEndpoint[] endPoints = new ServiceEndpoint[Description.Endpoints.Count]; Description.Endpoints.CopyTo(endPoints, 0); foreach (ServiceEndpoint se in endPoints) { var commonParams = new BindingParameterCollection(); foreach (IServiceBehavior b in Description.Behaviors) { b.AddBindingParameters(Description, this, Description.Endpoints, commonParams); } var channel = new DispatcherBuilder().BuildChannelDispatcher(Description.ServiceType, se, commonParams); ChannelDispatchers.Add(channel); endPointToDispatcher[se] = channel; } //After the ChannelDispatchers are created, and attached to the service host //Apply dispatching behaviors. foreach (IServiceBehavior b in Description.Behaviors) { b.ApplyDispatchBehavior(Description, this); } foreach (KeyValuePair <ServiceEndpoint, ChannelDispatcher> val in endPointToDispatcher) { foreach (var ed in val.Value.Endpoints) { ApplyDispatchBehavior(ed, val.Key); } } }
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; } } } }