我希望能够收集几个验证实体,所有验证实体都共享相同的界面。这就是我想出的:
public interface Ivalidateable
{
bool IsValid(IValidateParam param);
}
public interface IValidateParam
{
}
public abstract EmployeeStrategy: Ivalidateable
{
public abstract bool IsValid(User user);
}
public abstract SpreadStrategy: IValidateable
{
public abstract bool IsAvlid(Campaign campaign);
}
public class User: IValidateParam
{}
public class Campaign: IValidateParam
{}
public EmployeeTypeStragtegy: EmployeeStrategy, IValidateable
{
public bool IsValid(User user)
{
if (new[]{'e',a','b}.Contains(user.userId.first().toString()))
return true;
return false;
}
}
public TrailSpreadStrategy: SpreadStrategy, IValidateable
{
public bool IsValid(Campaign campaign)
{
//logic goes here
}
}
public EvenpreadStrategy: SpreadStrategy:, IValidateable
{
public bool IsValid(Campaign campaign)
{
//logic goes here
}
}
public class ValidationFactory
{
private static List<IValidateable> stragtegies;
static ValidationFactory
{
strategies = new List<IValidateable>();
strategies.Add(new EmployeeTypeStragtegy());
strategies.Add(new TrailSpreadStrategy());
}
public bool IsValid(//Need to pass User/Campaign)
{
//what do I do here?
}
}
传递用户/广告系列的最佳方式是什么,以便我可以循环策略并检查IsValid?
答案 0 :(得分:3)
我是这样做的:
// campaign object class, and it's separate validator logic
public class Campaign
{
}
public class CampaignValidator : IValidationStrategy<Campaign>
{
public bool IsValid(Campaign test)
{
return true;
}
}
// framework stuff
public interface IValidationStrategy<T>
{
bool IsValid(T test);
}
public static class ValidationFactory
{
private readonly static Dictionary<Type, object> _typeValidators;
static ValidationFactory()
{
_typeValidators = new Dictionary<Type, object>();
_typeValidators[typeof(Campaign)] = new CampaignValidator();
}
public static bool IsValid<T>(T obj)
{
return ((IValidationStrategy<T>)_typeValidators[typeof(T)]).IsValid(obj);
}
}
之后,您可以调用ValidationFactory.IsValid(myObject);
,如果类型在工厂静态构造函数中,它将为您提供true / false。
验证工厂正在做一种DI / IOC事情,即您可以使用Ninject,Castle等来实现将类型映射到验证器类型。
你可以动态地或不同地做事情而不必以相同的方式构建字典 - 查看验证器实现的接口的泛型类型参数,或者搜索基于IValidationStrategy<>
的类并再次查看泛型类型参数。但上述内容快速而简单。
您是否有理由需要单独的验证器类?
答案 1 :(得分:1)
我建议您查看FluentValidation的嵌套和收集验证功能。如果您的策略包含对要与其一起验证的其他实体的引用,这应该可以在没有额外工厂和接口的情况下正常工作。
答案 2 :(得分:0)
这个怎么样?
更改所有IsValid以使用此原型(用户用户,广告系列广告系列),例如:
public EmployeeTypeStragtegy: EmployeeStrategy, IValidateable
{
public bool IsValid(User user, Campaign campaign)
{
return (new char[]{'e','a','b'}.Contains(user.userId.first().toString());
}
}
然后用适当的类型处理每个,这样他们都接受相同的参数。然后:
public bool IsValid(User user, Campaign campaign)
{
bool valid;
foreach (IValidateable iv in strategies)
{
if (!iv.IsValid(user, campaign))
valid = false;
}
// This returns true if all are valid, false if not (not sure if this is the logic you expect)
return valid;
}