2012-01-07 70 views
1

我有一個抽象類,用於在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代理

的問題是線return new T(BasicHttpBinding, address);中的的CreateClientForServiceAtEndpoint方法抽象類。它不會允許我將參數傳遞給構造函數。如何才能做到這一點?

+1

它有時可能是一個更好的選擇來引入一個初始化方法的接口 – 2012-01-07 10:50:38

回答

3

在這種情況下,你需要用Activator.CreateInstance創建返回的實例:

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

而且沒有必要的where T : new()限制。

編輯:馬克的評論後

因爲現在爲什麼要說一個T的構造函數什麼(其他然後new())如果提供的T沒有正確的構造函數Activator.CreateInstance可以拋出。

但是你可以用 創建一個抽象基類中添加一些額外的指南,您的API用戶:

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

而且使用它作爲類型限制:where T : ServiceImplClientBase。但它只能提供構造函數的提示,因爲派生類型可以將基類構造函數聲明爲private或protected。

+0

優秀的答案謝謝你 – John 2012-01-07 10:51:49

+0

第二個例子不起作用 - 那沒有說T的構造函數 – 2012-01-07 10:58:47

相關問題