I have an abstract class that I use to set default values in a WCF proxy. I want all my other proxies to derive from this class passing in the service client that was generated when they added a service reference. Therefore I have the following
public abstract class ProxyFactory<T> where T : new()
{
protected BasicHttpBinding BasicHttpBinding = new BasicHttpBinding();
public abstract T GetTranslationServiceClient();
protected ProxyFactory()
{
BasicHttpBinding.Security.Mode = BasicHttpSecurityMode.None;
}
protected T CreateClientForServiceAtEndpoint(string uri)
{
var address = new EndpointAddress(uri);
return new T(BasicHttpBinding, address);
}
}
So for instance if you had a project and added a service reference to WCF service called MyService you would have a generated class called MyServiceClient. Then I would create a new class called MyServiceProxy that would derive from this class where T would be of type MyServiceClient. This would allow me to have all my common configuration in done in the base and the only code I would need to write is an override for the CreateClientForServiceAtEndpoint with the url of the service.
public override MyServiceImplClient GetMyServiceClient()
{
return CreateClientForServiceAtEndpoint("http://localhost/MyServices/MyServiceImpl.svc");
}
The this derived class will be used as a factory so calling clients would create a new instance and invoke CreateClientForServiceAtEndpoint to get a preconfigured WCF proxy
The problem is the line return new T(BasicHttpBinding, address); in the CreateClientForServiceAtEndpoint method of the abstract class. It will not allow me to pass the parameters to the constructor. How can this be done?
In this case you need to create your returned instance with Activator.CreateInstance:
And there is no need for the
where T : new()restriction.EDIT: After Marc’s comment
Because there is now why to say anything about a
T‘s constructor (other thennew()) theActivator.CreateInstancecan throw if the suppliedTdoes not have the right constructor.But you can add some additional guide to your API users with the
creation of an abstract base class:
And use it as the type restriction:
where T : ServiceImplClientBase. But it can just provide a hint for the need of the constructor because derived types can declare the base constructor as private or protected.