我有一个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" };
}
我正在考虑制作一个自定义属性来装饰我的属性,这样从AD填充我的对象的代码就不需要对映射进行硬编码,而是我可以装饰属性来自动填充对象
从长远来看,我也可以摆脱这个“PropertiesToLoad”。你认为属性是解决这个问题的好方法吗?另一个问题是,如果我通过属性来解决这个问题,我是否可能会产生巨大的性能瓶颈,或者使用属性并不是真正的性能问题。
答案 0 :(得分:3)
使用反射和属性 比编译为IL的常规C#慢,但问题是:你做了多少?如果你没有做很多,你就不会注意到它。
有提高反射性能的方法,但它们非常先进。
这似乎是一种指定映射的合理方式(并且与大多数序列化和持久性框架相当 - 尽管通常也提供没有属性的单独API)。
对于(in)适当的用途,请参阅Eric Lippert's blog。
答案 1 :(得分:1)
我喜欢使用属性来解决这种问题,因为它有助于在代码中清楚地表明属性以某种方式被使用。将PropertiesToLoad放在一个地方(如上例所示)或属性声明点之间需要进行权衡。我倾向于发现使用属性有助于代码维护,因为如果删除或修改属性,我不必追捕更改。
至于性能,是的,它会导致性能下降,但不会很大。它是可测量的,但除非这是性能关键代码,否则您可能不会注意到。即使在那一点上,我猜你会发现更大的问题。如果属性反射成为问题,则可以通过使用缓存或其他方法来降低性能影响。
答案 2 :(得分: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查询通常比一些内存中操作慢,所以我期待结果。 :)