2009-05-22 60 views
4

我有一个DataContract类,我必须填写来自我们公司的Active Directory的值。适当使用自定义属性?

[DataContract(Namespace = Global.Namespace)] 
public class UserProfile 
{ 
    [DataMember(IsRequired = true, EmitDefaultValue = false)] 
    public string EmployeeID { get; private set; } 

    [DataMember(IsRequired = true, EmitDefaultValue = false)] 
    public string GivenName { get; private set; } 

    ... 

    public static readonly string[] PropertiesToLoad = new[] { "EmployeeID", "GivenName" }; 
} 

我正在考虑做一个自定义属性来装饰我的属性,因此,这将填补我的对象从广告的代码就不需要有映射硬编码的,但更愿意我可能只是装饰性自动填充对象。

从长远来看,我可能也能够摆脱这种“PropertiesToLoad”。你认为属性是解决这个问题的好方法吗?还有一个问题,如果我通过属性来解决这个问题,我可能会造成巨大的性能瓶颈,或者使用Attributes不是真正的性能问题。

回答

1

我喜欢使用属性来解决这种问题,因为它有助于在代码中明确指出该属性正在以某种方式使用。将PropertiesToLoad放置在一个地方(如上面的示例中)或属性声明的位置之间有一个折衷。我倾向于发现使用属性有助于代码维护,因为如果属性被删除或修改,我不必追查更改。

至于性能,是的,它会导致性能下降,但不是很大。它是可测量的,但除非这是性能关键代码,否则您可能不会注意到。即使在那个时候,我猜你会发现更大的问题。如果属性反射成为问题,则可以通过使用缓存或其他方法来减轻性能影响。

3

使用反射和属性慢于普通C#编译为IL,但问题是:你在做多少?如果你不是这样做的地段,你不会注意到它。

有些方法可以提高反射的性能,但它们相当先进。

这似乎是一种指定映射的合理方式(并且与大多数序列化和持久性框架相当 - 尽管通常也提供了不带属性的单独API)。

对于(在)适当的用途,请参阅Eric Lippert's blog

1

我结束了写下面的代码。

public class UserProfile 
{ 
    [DataMember(IsRequired = true, EmitDefaultValue = false)] 
    [ActiveDirectoryProperty] 
    public string EmployeeID { get; set; } 


    [DataMember(IsRequired = true, EmitDefaultValue = false)] 
    [ActiveDirectoryProperty] 
    public string GivenName { get; set; } 


    [DataMember(IsRequired = true, EmitDefaultValue = false)] 
    [ActiveDirectoryProperty("SN")] 
    public string Surname { get; set; } 


    [DataMember(IsRequired = true, EmitDefaultValue = false)] 
    [ActiveDirectoryProperty] 
    public string Company { get; set; } 


    [DataMember(IsRequired = true, EmitDefaultValue = false)] 
    [ActiveDirectoryProperty] 
    public string Department { get; set; } 


    [DataMember(IsRequired = true, EmitDefaultValue = false)] 
    [ActiveDirectoryProperty("CN")] 
    public string UserName { get; set; } 


    [DataMember(IsRequired = true, EmitDefaultValue = false)] 
    [ActiveDirectoryProperty("Mail")] 
    public string Email { get; set; } 


    [DataMember(IsRequired = true, EmitDefaultValue = false)] 
    [ActiveDirectoryProperty] 
    public LanguageType Language { get; set; } 


    [DataMember(IsRequired = true, EmitDefaultValue = false)] 
    public DateTime? NextPasswordChangeDate { get; set; } 
} 

然后我可以使用反射来获取旧的“PropertiesToLoad”这本身是无害的大部分,因为我使用反射只有一次,以填补后一个数组,我不需要再调用GetProperties中。

唯一需要测试的是,如果我可以从SearchResult快速填充对象 - 但是,tbh,AD查询通常比内存中的某些操作要慢,所以我期待着结果。 :)