将参数传递给在抽象类中创建的新泛型类

本文关键字:创建 泛型类 抽象类 参数传递 | 更新日期: 2023-09-27 18:19:37

我有一个抽象类,用于在WCF代理中设置默认值。我希望我的所有其他代理都是从这个类派生的,该类传入在添加服务引用时生成的服务客户端。因此,我有以下

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);
    }
}

因此,例如,如果您有一个项目,并向WCF服务添加了一个名为MyService的服务引用,那么您将生成一个称为MyServiceClient的类。然后,我将创建一个名为MyServiceProxy的新类,该类将从该类派生,其中T的类型为MyServiceClient。这将允许我在库中完成所有常见配置,并且我需要编写的唯一代码是用服务的url覆盖CreateClientForServiceAtEndpoint

public override MyServiceImplClient GetMyServiceClient()
{
    return CreateClientForServiceAtEndpoint("http://localhost/MyServices/MyServiceImpl.svc");
}

该派生类将用作工厂,因此调用客户端将创建一个新实例并调用CreateClientForServiceAtEndpoint以获得预配置的WCF代理

问题是抽象类的CreateClientForServiceAtEndpoint方法中的行return new T(BasicHttpBinding, address);。它不允许我将参数传递给构造函数。如何做到这一点?

将参数传递给在抽象类中创建的新泛型类

在这种情况下,您需要使用Activator.CreateInstance:创建返回的实例

protected T CreateClientForServiceAtEndpoint(string uri)
{
    var address = new EndpointAddress(uri);
    return (T) Activator.CreateInstance(typeof(T), BasicHttpBinding, address);
}

并且不需要CCD_ 9限制。

编辑:马克评论后

因为现在有理由说T的构造函数(而不是new()),如果提供的T没有正确的构造函数,Activator.CreateInstance可以抛出。

但您可以使用添加一些附加指南给API用户创建一个抽象基类:

public abstract class ServiceImplClientBase
{
    public ServiceImplClientBase(BasicHttpBinding basicHttpBinding, EndpointAddress endpointAddress)
    {
        //...
    }
}

并将其用作类型限制:where T : ServiceImplClientBase。但它只能为构造函数的需要提供提示,因为派生类型可以将基构造函数声明为私有或受保护。