Implement a service delivery contract at runtime in WCF

How do I enable the implementation of the service contract at runtime?

Let's say I have:

[ServiceContract]
public interface IService {
    [OperationContract]
    DoWork();
}

public class ServiceA : IService {
    public string DoWork() {
        // ....
    }
}

public class ServiceB : IService {
    public string DoWork() {
        // ....
    }
}

      

I would like to be able to switch the implementation that is used from the config file or the value in the database between the two. Is it possible to do this while the WCF service is hot?

+3


source to share


1 answer


You need to write a servicebehavior by executing an IServiceBehavior and initialize a service instance using an instance provider. After initializing a new instance of the service, you can implement other logic:

public class XInstanceProviderServiceBehavior : Attribute, IServiceBehavior
{        

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        foreach (var item in serviceHostBase.ChannelDispatchers)
        {
            var dispatcher = item as ChannelDispatcher;
            if (dispatcher != null) 
            {
                dispatcher.Endpoints.ToList().ForEach(endpoint =>
                {
                    endpoint.DispatchRuntime.InstanceProvider = new XInstanceProvider(serviceDescription.ServiceType);
                });
            }
        }
    }

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
    }

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
    }
}

      

And let your instance of the provider class implement IInstanceProvider and return the corresponding instance in the GetInstance method.



public XInstanceProvider :IInstanceProvider
{
    ...

    public object GetInstance(InstanceContext instanceContext, System.ServiceModel.Channels.Message message)
    {
        return new ServiceX();
    }
}

      

Then you need to add a servicebehaviour for service; something like

[XInstanceProviderServiceBehavior()]    
    public class MyService : IMyService

      

+3


source







All Articles