我有一个类似的验证界面:
public interface IValidation<T> {
bool IsValid(T item, ref AggregateException fail);
}
我有一个需要多个验证接口的文件导入器
public FileImporter {
IEnumerable<IValidation<Patient>> Validators { get; set; }
public FileImporter(IWindsorContainer container) {
// the ResolveAll method does not do this
Validators = container.ResolveAll<IValidation<Patient>>("fileValidation");
}
}
我还有另一个类有更多验证器,但使用的是FileImporter
中使用的一些类。
public PatientService {
IEnumerable<IValidation<Patient>> Validators { get; set; }
public PatientService(IWindsorContainer container) {
// the ResolveAll method does not do this
Validators = container.ResolveAll<IValidation<Patient>>("userInputValidation");
}
}
例如,我有两个验证器LastNameValidator
和DateOfBirthValidator
。 LastNameValidator is used in both the
FileImporter and the
PatientService .
DateOfBirthValidator is only used in the
PatientService`类。这两个类的实现都在问题之下。
我的问题是如何连接这两个类,以便按上述方式使用它们。我应该采用什么方法来解决它们?
public class LastNameValidator : IValidation<Patient> {
public bool IsValid(Patient p, ref AggregateException fail) {
var isValid = !string.IsNullOrWhitespace(p.LastName))
if (!isValid)
// update fail
return isValid;
}
}
public class DateOfBirthValidator : IValidation<Patient> {
public bool IsValid(Patient p, ref AggregateException fail) {
if (!p.DateOfBirth.HasValue) {
// update fail, can't be empty
return false;
}
if (p.DateOfBirth.Value > DateTime.Now) {
// update fail, can't be in future
return false;
}
return true;
}
}
答案 0 :(得分:1)
我会考虑Typed Factory Facility。您可以使用名称“lastnamevalidator”和“dobvalidator”注册验证器。然后创建一个工厂界面来抓取那些特定的验证器。您只需要接口 - 工具将执行:
public interface IValidatorFactory
{
IValidator GetLastNameValidator();
IValidator GetDobValidator();
}
现在将IValidatorFactory传递给您的组件。这也消除了传递Windsor容器的需要(这不是一个好主意,因为它将您的代码紧密地耦合到Windsor并使单元测试更加困难)。
现在只需调用工厂方法来访问每个组件所需的特定验证器。
<强>更新强>
仍然不清楚你的系统的哪个部分将决定使用哪个IValidator,但也许这会起作用。使用基于IValidator
的标记接口。
public interface IFileValidator : IValidator
{
}
public interface IUserInputValidator : IValidator
{
}
现在让您的验证器根据它们的使用位置实现标记接口 - 并记住您可以实现多个接口,因此验证器可以在多种情况下使用。例如:
public class FileValidator : IFileValidator
{
public bool IsValid()
{
return false;
}
}
public class DobValidator : IUserInputValidator, IFileValidator
{
public bool IsValid()
{
return false;
}
}
public class LastNameValidator : IUserInputValidator
{
public bool IsValid()
{
return true;
}
}
更改工厂界面以仅返回特定类型的验证器:
public interface IValidatorFactory
{
IFileValidator[] GetFileValidators();
IUserInputValidator[] GetUserInputValidators();
}
现在将验证者accorindg注册到他们的“类型”。如果验证器有多种用途,请务必为Windsor添加.Forward<>
定义:
var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(
Component.For<IValidatorFactory>().AsFactory(),
Component.For<IFileValidator>().ImplementedBy<FileValidator>(),
Component.For<IUserInputValidator>().ImplementedBy<LastNameValidator>(),
Component.For<IFileValidator>().Forward<IUserInputValidator>().ImplementedBy<DobValidator>()
);