2014-04-03 81 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

相关问题