Beispiel #1
0
        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();
        }
Beispiel #2
0
        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;
                    }
                }
            }
        }