我正在創建一個規則集引擎,看起來有點像單元測試框架。如何從方法實例中創建枚舉<Func<>>
[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。
我仍然可以在我的select語句訪問 「類型」。這只是一個「let」語句,用於創建一個臨時變量,而不是用於轉換類型的「select」語句。順便說一句:這不應該是一個評論,而不是一個答案? – Tormod
我相信我回答了主要問題,儘管我現在看到主要問題沒有被實際詢問。我認爲主要問題是如何收集所有方法的規則屬性。不是嗎? – Dialecticus