1

Is there any way to extend ServiceHost so that it accepts a factory?

I would like to use dynamic service proxies for some preprocessing of WCF calls without touching the service implementation.

EDIT

Now the ServiceHost creation looks like

var host = new ServiceHost(typeof(MyService));

and i would like to use something like

var factory = new ServiceProxyFactory<MyService>();
var host = new MyServiceHost(typeof(MyService), factory);
Bohdan
  • 1,930
  • 15
  • 19
  • 1
    NO, that's not possible. There's a mechanism to have a factory for the service hosts - but there's no way to have the service hosts take in a factory to create the actual service instances – marc_s Sep 12 '11 at 21:19
  • @marc_s I thought the same BUT it is possible... see answers below... – Yahia Sep 13 '11 at 16:34
  • @yahia: interesting - thanks for the links! I'll have to study those in more detail ! – marc_s Sep 13 '11 at 17:22

2 Answers2

3

The interface i was looking for is IInstanceProvider.

public class MyServiceInstanceProvider<TService> : IInstanceProvider where TService : new()
{

    public object GetInstance(InstanceContext instanceContext, System.ServiceModel.Channels.Message message)
    {
        return ServiceFactory.Create<TService>();
    }

    public object GetInstance(InstanceContext instanceContext)
    {
        return ServiceFactory.Create<TService>();
    }

    public void ReleaseInstance(InstanceContext instanceContext, object instance)
    {
        return;
    }
}

public class MyEndpointBehavior<TService> : IEndpointBehavior where TService : new()
{

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
        return;
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        return;
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        endpointDispatcher.DispatchRuntime.InstanceProvider = new MyServiceInstanceProvider<TService>();
    }

    public void Validate(ServiceEndpoint endpoint)
    {
        return;
    }
}

public class MyServiceHost<TService> : ServiceHost where TService : new()
{
    public MyServiceHost(params Uri[] baseAddresses)
        :base(typeof(TService), baseAddresses)
    {            
    }

    public override System.Collections.ObjectModel.ReadOnlyCollection<ServiceEndpoint> AddDefaultEndpoints()
    {
        var endpoints = base.AddDefaultEndpoints();

        foreach (var endpoint in endpoints)
        {
            endpoint.Behaviors.Add(new MyEndpointBehavior<TService>());
        }

        return endpoints;
    }

    public override void AddServiceEndpoint(ServiceEndpoint endpoint)
    {
        base.AddServiceEndpoint(endpoint);
        endpoint.Behaviors.Add(new MyEndpointBehavior<TService>());
    }

}
Bohdan
  • 1,930
  • 15
  • 19
2

What you describe is not really possible with .NET...

You can implement a custom ServiceHost which allows you to customize the behaviour of the ServiceHost and/or the IDispatchMessageInspector which allows you inspect/modify any message inbound and outbound... IF you really wnat to implement some sort of "dynamic routing" then there is always the Routing capability of WCF...

Other options (though no 100% solution):

EDIT - I stand corrected:

It is not really possible to use a usual Factory BUT WCF provides the possibility to plug in an IInstanceProvider either at the Service or the Endpoint level...

For further reference see the following links

Community
  • 1
  • 1
Yahia
  • 67,016
  • 7
  • 102
  • 131