Appropriate use of custom attributes?

I have a DataContract class that I have to populate with values ​​from our company’s 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" }; } 

I was considering creating a custom attribute to decorate my properties, so for the code that was supposed to fill my object from AD, I would not need to have a map binding, but I could just decorate the properties to automatically fill the object.

And in the end, I could also get rid of this "PropertiesToLoad". Do you think Attributes are a good way to solve this problem? And one more question, if I solve this with attributes, I will probably make a huge neck of the performance bottle or use attributes that are not a performance issue.

+4
source share
3 answers

I like to use attributes for such a concern, because it helps to understand in the code that the property is being used in a certain way. There is a trade-off between the PropertiesToLoad scope in one place (as in the example above) or at the property declaration point. I believe that using attributes helps maintain code because I don’t need to track changes if the property is deleted or changed.

In terms of performance, yes, this will lead to a performance hit, but not a huge one. This is measurable, but if this is not a critical performance code, you probably won't notice. And even at that moment, I suppose, you will find more problems. If attribute reflection becomes a problem, there is a way to reduce the impact of performance using caching or other methods.

+1
source

Using reflection and attributes is slower than regular C # compiled as IL, but the question is: how much do you do this? If you do not complete the lots , you will not notice this.

There are ways to improve reflection performance, but they are pretty advanced.

This seems like a reasonable way of specifying a mapping (and is comparable to most serialization and persistence schemes), although a separate API without attributes is often provided).

For (for) relevant purposes, see Eric Lippert's blog .

+3
source

I ended up writing the following code.

 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; } } 

Then I can use reflection to get the old "PropertiesToLoad", which itself is basically harmless, since I use reflection only once to fill the array after that, I no longer need to call GetProperties.

The only thing that remains to be checked: if I can fill out the object from SearchResult fast enough, but, tbh, the AD query is usually slower than some RAM operations, so I look forward to the result :)

+1
source

All Articles