2014-04-03 124 views
3

我有一個Client類,它在構造函數中接受具有IConfiguration接口的對象。構造函數重構中的虛擬方法調用

當創建對象時,應該驗證配置。

public interface IConfiguration 
{ 
    int ReconnectDelay { get; } 
} 

public class Client 
{ 
    public Client(IConfiguration configuration) 
    { 
     if (configuration.ReconnectDelay < 60000) 
     { 
      throw new ConfigurationErrorsException(); 
     } 
    } 
} 

出於測試目的,我需要一個客戶端與ReconnectDelay屬性設置爲一個值小於有效。

這是我目前的解決方案:

public class Client 
{ 
    public Client(IConfiguration configuration) 
    { 
     ValidateConfiguration(configuration); 
    } 

    protected virtual void ValidateConfiguration(IConfiguration configuration) 
    { 
     if (configuration.ReconnectDelay < 60000) 
     { 
      throw new ConfigurationErrorsException(); 
     } 
    } 
} 

public class TestClient : Client 
{ 
    public TestClient(IConfiguration configuration) 
     : base(configuration) 
    { 
    } 

    protected override void ValidateConfiguration(IConfiguration configuration) 
    { 
    } 
} 

它的工作原理,但會導致調用在構造虛擬方法,這是不好的(我知道現在它不會有什麼壞處,但我無論如何要解決這個問題)。

那麼,有沒有優雅的解決方案呢?

+0

你可以讓'TestClient'類成爲'sealed'嗎? – Dmitry

+0

@Dmitry這將如何幫助?誠實的問題。 –

+0

@Dmitry,我可以使'TestClient'成爲密封的,但這裏的問題與'Client'類有關。 – bniwredyc

回答

2

您可以使用2個實現創建Validator接口,然後委託給驗證器。從技術上講,這仍然是一個虛擬的通話,但它是針對另一個對象的,因此您不必擔心Client的子類覆蓋該通話或訪問部分構建的客戶端。

public interface IValidator 
{ 
    bool Validate (IConfiguration configuration); 
} 

然後你的正常用例使用ReconnectionValidator。

public class ReconnectionValidator : IValidator 
{ 

    bool Validate (IConfiguration configuration) 
    { 
     return configuration.ReconnectDelay >= 60000; 
    } 
} 

您的測試驗證可以隨時返回true,那麼

public class NullValidator : IValidator 
{ 

    bool Validate (IConfiguration configuration) 
    { 
     return true; 
    } 
} 

客戶端代碼將採取兩個IValidator,並在其構造和測試的IConfiguration如果校驗驗證配置。

public Client(IConfiguration configuration, IValidator validator) 
{ 
    if(!validator.Validate(configuration)) 
    { 
     throw new ConfigurationErrorsException(); 
    } 
} 

這種技術的好處是,你可以在以後更改驗證或有新的實現,鏈幾個驗證共同支持「或」 ING和「安定」驗證器一起。

+0

謝謝,我喜歡你的解決方案。 – bniwredyc

+0

@bniwredyc很棒。我只是在我的ReconnectionValidator代碼中修復了一個錯誤,因爲我反向布爾邏輯會失敗 – dkatzel

相關問題