So, im trying to write routing service. The idea is that, every time someone calls routing service, endpoint is randomly selected by WCF behavior extension. I used slightly modified example from MSDN called DynamicReconfiguration to achieve that. Part of my web.config looks like this
<behaviors>
<serviceBehaviors>
<behavior>
<behavior name="behaviorWithUpdate">
<updateBehavior />
</behavior>
</serviceBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="updateBehavior" type="RouterService.UpdateBehavior, RouterService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
<services>
and implementation of behavior and behavior extension
public class UpdateBehavior : BehaviorExtensionElement, IServiceBehavior
{
void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
var rulesUpdateExtension = new RulesUpdateExtension();
serviceHostBase.Extensions.Add(rulesUpdateExtension);
}
void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
class RulesUpdateExtension : IExtension<ServiceHostBase>
{
ServiceHostBase _owner;
List<EndpointAddress> _endpoints = new List<EndpointAddress>
{
new EndpointAddress("http://localhost:19338/Service1.svc"),
new EndpointAddress("http://localhost:20464/Service2.svc")
};
void IExtension<ServiceHostBase>.Attach(ServiceHostBase owner)
{
this._owner = owner;
UpdateRules(DateTime.Now.Second % 2 == 0 ? _endpoints[0] : _endpoints[1]);
}
void IExtension<ServiceHostBase>.Detach(ServiceHostBase owner)
{
}
void UpdateRules(EndpointAddress endpoint)
{
var rc = new RoutingConfiguration();
var serviceEndpoint = new ServiceEndpoint(
ContractDescription.GetContract(typeof(IService1)),
new BasicHttpBinding(),
endpoint);
rc.FilterTable.Add(new MatchAllMessageFilter(), new List<ServiceEndpoint> { serviceEndpoint });
this._owner.Extensions.Find<RoutingExtension>().ApplyConfiguration(rc);
}
}
public override Type BehaviorType
{
get { return typeof(UpdateBehavior); }
}
protected override object CreateBehavior()
{
return new UpdateBehavior();
}
}
Problem is that last line of UpdateRules method is throwing NullReferenceException. It cant find this extension even though i attach it in behavior. In example from MSDN, routing service is hosted in console application and here im trying to host it on IIS. Im missing something here...
In the sample RoutingService project, the code in the routing.cs programmatically injects the RoutingExtension into the RoutingService. This is normally done in the config file using the behaviors>serviceBehaviors>behavior>routing element to set up the filter table to use. However, since a WCF service can only be assigned a single service behavior through the config file, the sample RoutingService project dynamically adds the RoutingExtension in the service host initialization.
To do the same thing in IIS, you need to create a custom service host factory to perform the same function of the routing.cs code in the sample project. Look at this MSDN article for how to create a custom host. It also shows how you would configure it with IIS.