194 lines
8.0 KiB
C#
194 lines
8.0 KiB
C#
|
//----------------------------------------------------------------
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//----------------------------------------------------------------
|
||
|
|
||
|
namespace System.ServiceModel.Discovery
|
||
|
{
|
||
|
using System.Collections.Generic;
|
||
|
using System.Collections.ObjectModel;
|
||
|
using System.Diagnostics.CodeAnalysis;
|
||
|
using System.Runtime;
|
||
|
using System.ServiceModel.Channels;
|
||
|
using System.ServiceModel.Description;
|
||
|
using System.ServiceModel.Dispatcher;
|
||
|
|
||
|
[Fx.Tag.XamlVisible(false)]
|
||
|
public class ServiceDiscoveryBehavior : IServiceBehavior
|
||
|
{
|
||
|
NonNullItemCollection<AnnouncementEndpoint> announcementEndpoints;
|
||
|
|
||
|
public ServiceDiscoveryBehavior()
|
||
|
{
|
||
|
this.announcementEndpoints = new NonNullItemCollection<AnnouncementEndpoint>();
|
||
|
}
|
||
|
|
||
|
public Collection<AnnouncementEndpoint> AnnouncementEndpoints
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return this.announcementEndpoints;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[SuppressMessage(FxCop.Category.Design, FxCop.Rule.InterfaceMethodsShouldBeCallableByChildTypes)]
|
||
|
void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints,
|
||
|
BindingParameterCollection bindingParameters)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
[SuppressMessage(FxCop.Category.Design, FxCop.Rule.InterfaceMethodsShouldBeCallableByChildTypes)]
|
||
|
void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
|
||
|
{
|
||
|
if (serviceDescription == null)
|
||
|
{
|
||
|
throw FxTrace.Exception.ArgumentNull("serviceDescription");
|
||
|
}
|
||
|
if (serviceHostBase == null)
|
||
|
{
|
||
|
throw FxTrace.Exception.ArgumentNull("serviceHostBase");
|
||
|
}
|
||
|
|
||
|
List<ServiceEndpoint> appEndpoints = this.GetApplicationEndpoints(serviceDescription);
|
||
|
|
||
|
DiscoveryServiceExtension discoveryServiceExtension =
|
||
|
serviceHostBase.Extensions.Find<DiscoveryServiceExtension>();
|
||
|
|
||
|
if (discoveryServiceExtension == null)
|
||
|
{
|
||
|
if (serviceDescription.Endpoints.Count > appEndpoints.Count)
|
||
|
{
|
||
|
discoveryServiceExtension =
|
||
|
new DefaultDiscoveryServiceExtension(DiscoveryDefaults.DuplicateMessageHistoryLength);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
discoveryServiceExtension =
|
||
|
new DefaultDiscoveryServiceExtension(0);
|
||
|
}
|
||
|
|
||
|
serviceHostBase.Extensions.Add(discoveryServiceExtension);
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < appEndpoints.Count; i++)
|
||
|
{
|
||
|
appEndpoints[i].Behaviors.Add(
|
||
|
new EndpointDiscoveryMetadataInitializer(
|
||
|
discoveryServiceExtension.InternalPublishedEndpoints));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[SuppressMessage(FxCop.Category.Design, FxCop.Rule.InterfaceMethodsShouldBeCallableByChildTypes)]
|
||
|
void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
|
||
|
{
|
||
|
if (serviceDescription == null)
|
||
|
{
|
||
|
throw FxTrace.Exception.ArgumentNull("serviceDescription");
|
||
|
}
|
||
|
if (serviceHostBase == null)
|
||
|
{
|
||
|
throw FxTrace.Exception.ArgumentNull("serviceHostBase");
|
||
|
}
|
||
|
|
||
|
DiscoveryServiceExtension discoveryServiceExtension = serviceHostBase.Extensions.Find<DiscoveryServiceExtension>();
|
||
|
if (discoveryServiceExtension != null)
|
||
|
{
|
||
|
DiscoveryService discoveryService = discoveryServiceExtension.ValidateAndGetDiscoveryService();
|
||
|
|
||
|
ServiceDiscoveryBehavior.SetDiscoveryImplementation(serviceHostBase, discoveryService);
|
||
|
|
||
|
if (this.announcementEndpoints.Count > 0)
|
||
|
{
|
||
|
serviceHostBase.ChannelDispatchers.Add(
|
||
|
new OnlineAnnouncementChannelDispatcher(
|
||
|
serviceHostBase,
|
||
|
this.announcementEndpoints,
|
||
|
discoveryServiceExtension.InternalPublishedEndpoints,
|
||
|
discoveryService.MessageSequenceGenerator));
|
||
|
|
||
|
serviceHostBase.ChannelDispatchers.Insert(0,
|
||
|
new OfflineAnnouncementChannelDispatcher(
|
||
|
serviceHostBase,
|
||
|
this.announcementEndpoints,
|
||
|
discoveryServiceExtension.InternalPublishedEndpoints,
|
||
|
discoveryService.MessageSequenceGenerator));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void SetDiscoveryImplementation(ServiceHostBase host, DiscoveryService discoveryService)
|
||
|
{
|
||
|
foreach (ChannelDispatcherBase channelDispatcherBase in host.ChannelDispatchers)
|
||
|
{
|
||
|
ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
|
||
|
if (channelDispatcher != null)
|
||
|
{
|
||
|
foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
|
||
|
{
|
||
|
if ((endpointDispatcher != null) && EndpointDiscoveryMetadata.IsDiscoverySystemEndpoint(endpointDispatcher))
|
||
|
{
|
||
|
SetDiscoveryImplementation(endpointDispatcher, discoveryService);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void SetDiscoveryImplementation(EndpointDispatcher endpointDispatcher, DiscoveryService discoveryService)
|
||
|
{
|
||
|
DispatchRuntime dispatchRuntime = endpointDispatcher.DispatchRuntime;
|
||
|
dispatchRuntime.SynchronizationContext = null;
|
||
|
dispatchRuntime.ConcurrencyMode = ConcurrencyMode.Multiple;
|
||
|
ServiceDiscoveryInstanceContextProvider provider = new ServiceDiscoveryInstanceContextProvider(discoveryService);
|
||
|
dispatchRuntime.InstanceContextProvider = provider;
|
||
|
dispatchRuntime.InstanceProvider = provider;
|
||
|
dispatchRuntime.Type = discoveryService.GetType();
|
||
|
}
|
||
|
|
||
|
List<ServiceEndpoint> GetApplicationEndpoints(ServiceDescription serviceDescription)
|
||
|
{
|
||
|
List<ServiceEndpoint> appEndpoints = new List<ServiceEndpoint>(serviceDescription.Endpoints.Count);
|
||
|
foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints)
|
||
|
{
|
||
|
if (!EndpointDiscoveryMetadata.IsDiscoverySystemEndpoint(endpoint))
|
||
|
{
|
||
|
appEndpoints.Add(endpoint);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return appEndpoints;
|
||
|
}
|
||
|
|
||
|
class EndpointDiscoveryMetadataInitializer : IEndpointBehavior
|
||
|
{
|
||
|
Collection<EndpointDiscoveryMetadata> publishedEndpointCollection;
|
||
|
|
||
|
internal EndpointDiscoveryMetadataInitializer(Collection<EndpointDiscoveryMetadata> publishedEndpointCollection)
|
||
|
{
|
||
|
this.publishedEndpointCollection = publishedEndpointCollection;
|
||
|
}
|
||
|
|
||
|
void IEndpointBehavior.AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
|
||
|
{
|
||
|
EndpointDiscoveryMetadata endpointDiscoveryMetadata = EndpointDiscoveryMetadata.FromServiceEndpoint(endpoint, endpointDispatcher);
|
||
|
|
||
|
if (endpointDiscoveryMetadata != null)
|
||
|
{
|
||
|
this.publishedEndpointCollection.Add(endpointDiscoveryMetadata);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void IEndpointBehavior.Validate(ServiceEndpoint endpoint)
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|