我正在创建一个看起来有点像单元测试框架的规则集引擎。
[RuleSet(ContextA)]
public class RuleSet1
{
[Rule(TargetingA)]
public Conclusion Rule1(SubjectA subject)
{ Create conclusion }
[Rule(TargetingA)]
public Conclusion Rule2(SubjectA subject)
{ Create conclusion }
[Rule(TargetingB)]
public Conclusion Rule3(SubjectB subject)
{ Create conclusion }
}
[RuleSet(ContextB)]
public class RuleSet2
{
[Rule(TargetingB)]
public Conclusion Rule1(SubjectB subject)
{ Create conclusion }
[Rule(TargetingA)]
public Conclusion Rule2(SubjectA subject)
{ Create conclusion }
[Rule(TargetingB)]
public Conclusion Rule3(SubjectB subject)
{ Create conclusion }
}
public class Conclusion()
{
// Errorcode, Description and such
}
// contexts and targeting info are enums.
目标是创建一个可扩展的规则集,该规则集不会从消费者 POV 更改 API,同时在代码文件中具有良好的关注点分离。再次:就像一个单元测试框架。
我正在尝试创建一个公开以下 API 的库
public static class RuleEngine
{
public static IEnumerable<IRuleSet> RuleSets(contextFlags contexts)
{
{
return from type in Assembly.GetExecutingAssembly().GetTypes()
let attribute =
type.GetCustomAttributes(typeof (RuleSetAttribute), true)
.OfType<RuleSetAttribute>()
.FirstOrDefault()
where attribute != null
select ?? I don't know how to convert the individual methods to Func's.
}
}
}
internal interface IRuleset
{
IEnumerable<Func<SubjectA, Conclusion>> SubjectARules { get; }
IEnumerable<Func<SubjectB, Conclusion>> SubjectBRules { get; }
}
...允许消费者像这样简单地使用(在本示例中使用 foreach 而不是 LINQ 以提高可读性)
foreach (var ruleset in RuleEgine.RuleSets(context))
{
foreach (var rule in ruleset.SubjectARules)
{
var conclusion = rule(myContextA);
//handle the conclusion
}
}
此外,如果您能告诉我如何摆脱“TargetingA”和“TargetingB”作为 RuleAttribute 参数,而是使用反射直接检查修饰方法的参数类型,那将非常有帮助。同时维护相同的简单外部 API。