Search code examples
c#asp.netwcfiissvc

WCF - Implementing a ServiceHostFactory to use into IIS context (svc file)


I've successfully implemented a self-hosted WCF service. For legacy matters, the host binding configuration is read from a non-standard source (instead of app.config). When porting this service to IIS, I run into the problem of loading the settings and I found that the solution would involve implementing a class inherited from ServiceHostFactory.

My problem, though, is that the CreateServiceHost method only receives the concrete type and the URI from the SVC file, but I wanted to re-use this class to further implementations and need more information: like the interface that defines the ServiceContract and the binding already configured.

I found this excellent article from @carlosfigueira, but its implementation uses the factory to return a host that is specific to the service, in a 1-to-1 relation. I sure can do it, but that will lead to several specific factories, with lots of copy-and-paste code and I'd ratter avoid it. Is it possible? If so, how can I do it?


Solution

  • There is no built-in way of finding out which contracts are implemented by a service class, but the code shouldn't be too hard. It's something along the lines of the function below. You'll need some logic to determine the relative address if you have multiple contract types (i.e., if you have a single contract, use "", if you have multiple, use the contract name as the address).

    private IEnumerable<Type> GetContractType(Type serviceType) 
    { 
        if (HasServiceContract(serviceType))
        { 
            yield return serviceType; 
        } 
    
        var contractInterfaceTypes = serviceType.GetInterfaces() 
            .Where(i => HasServiceContract(i));
    
        foreach (var type in contractInterfaceTypes)
        {
            yield return type;
        }
    
        // if you want, you can also go to the service base class,
        // interface inheritance, etc.
    } 
    
    private static bool HasServiceContract(Type type) 
    { 
        return Attribute.IsDefined(type, typeof(ServiceContractAttribute), false); 
    }