我有一个Client
类,它接受构造函数中带有IConfiguration
接口的对象。
配置应在创建Client
对象时验证。
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 :(得分: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();
}
}
这种技术的好处是你可以稍后更改验证器,或者有一个新的实现,将多个验证器链接在一起以支持&#34;或&#34;和&#34; anding&#34;验证者在一起。