2011-10-04 71 views
0

我有一个定义了很多规则的XML文件。 我将XML文件加载到我的规则引擎中。规则引擎的动态加载类

根据我加载的XML文件,我需要选择哪个命名空间,我会找到我需要的类。然后在XML的每一行上,我需要确定要加载的类。

我的XML

<RuleList assembly="BMW"> 
<rule> 
    <code>2345</code> 
    <errorMessage>foo bar</errorMessage> 
    <order>1</order> 
</rule> 
</RuleList> 
<RuleList assembly="FORD"> 
<rule> 
    <code>0045</code> 
    <errorMessage>foo bar</errorMessage> 
    <order>3</order> 
</rule> 
</RuleList> 

我只能一次处理一个规则列表。

我是否应该为定义要加载的ClassName的每个规则添加额外的XML属性? 因为我不想使用代码作为类名?或者,我可以只添加代码到我的类中的属性,并用它来动态

加载例如

namespace FORD 
{ 
    [code=0045] 
    public bool IsValidColor(foo) : IisValid 
    { 
     return true 
    } 
} 

我可以加载的类从[代码= 0045】或者我应该只是存储“ IsValidColor“。是否有性能差异?

回答

1

您的属性语法不起作用。但是像[Code("0045")]这样的东西,如果你创建CodeAttribute

会有一些性能差异,因为您必须根据程序集中所有类型的属性找到正确的类型。但差异很可能会微不足道。

真正做到这一点,将属性定义是这样的:

[AttributeUsage(AttributeTargets.Class)] 
class CodeAttribute : Attribute 
{ 
    public CodeAttribute(string code) 
    { 
     Code = code; 
    } 

    public string Code { get; private set; } 
} 

,然后找到像这样的类:

var type = 
    (from t in assembly.GetTypes() 
    let attr = (CodeAttribute)t 
        .GetCustomAttributes(typeof(CodeAttribute), false) 
        .SingleOrDefault() 
    where attr != null && attr.Code == code 
    select t) 
    .Single(); 
+0

所以如果我使用[Code(“0045”)]语法。我如何实际过滤?有没有像我可以在Assembly类上使用的linq查询 – Daveo

+0

是的,你必须使用'Assembly.GetTypes()'然后检查每个类型的属性。请参阅编辑。 – svick

1

任一选项都具有相似的性能。如果错误代码,错误消息,并且为了将永远不会通过XML文件有所不同,你甚至可以拥有所有的元数据的约,而不是一个属性的内部规则,并在运行时通过实现IisValid所有类枚举:

[Rule(Code = "0045", ErrorMessage = "foo bar", Order = 1)] 
public class IsValidColor : IisValid 
{ 
    public bool IsValid(Foo bar) 
    { 
     // validation rules here 
    } 
} 

但是,如果所有这些都是可定制的,那么我会让XML文件指定要使用的类的名称。

+0

好感谢的,是唯一的代码不会改变,所有其他属性将可定制。所以我可以在我的XML中添加。 – Daveo